You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SAS中识别空格分隔值的正则模式并拆分至多列

SAS多值字段按指定正则模式拆分解决方案

现有数据集

1. hogwarts数据集

生成代码:

DATA hogwarts;
INFILE DATALINES delimiter="," dsd;
LENGTH Index Wizards $ 255;
INPUT Index Wizards $ Points;
DATALINES;
1,'Harry Potter Ron Weasley',100
2,'Hermione Granger Harry Potter',200
3,'Ron Weasley',300
;
RUN;

数据集结构:

IndexWizardsPoints
1Harry Potter Ron Weasley100
2Hermione Granger Harry Potter200
3Ron Weasley300

2. wizards数据集

生成代码:

DATA wizards;
INPUT Name $64.;
DATALINES;
Harry Potter
Ron Weasley
Hermione Granger
;
RUN;

数据集结构:

Name
Harry Potter
Ron Weasley
Hermione Granger

需求说明

匹配wizards数据集中的姓名模式,将hogwarts的Wizards列内容按出现位置拆分,生成Wizard1、Wizard2……WizardN列,输出数据集want结构如下:

IndexWizardsPointsWizard1Wizard2
1Harry Potter Ron Weasley100Harry PotterRon Weasley
2Hermione Granger Harry Potter200Hermione GrangerHarry Potter
3Ron Weasley300Ron Weasley.

核心要求:

  • 拆分结果严格保留原内容中的出现顺序
  • 支持匹配单/多词组合的姓名模式
  • 兼容Wizards列中数量不固定的分隔空格
  • 根据实际匹配结果自动调整WizardN列的数量

实现方案

步骤1:生成正则匹配模板

从wizards数据集提取所有姓名,拼接成可精准匹配完整姓名的正则模式:

DATA _null_;
    SET wizards END=last;
    RETAIN regex_pattern;
    /* 拼接姓名为正则选择分支,添加引号避免部分匹配 */
    regex_pattern = catx('|', regex_pattern, quote(trim(Name), "'"));
    IF last THEN DO;
        regex_pattern = cats('(', regex_pattern, ')');
        CALL SYMPUT('regex', regex_pattern);
    END;
RUN;

步骤2:统计最大所需列数

遍历hogwarts数据集,统计每行匹配到的姓名数量,确定需要生成的WizardN列的最大数量:

DATA _max_count;
    SET hogwarts NOBS=_nobs;
    /* 统计当前行匹配到的姓名总数 */
    count = prxmatch(cats('/\s*&regex\s*/', 'g'), Wizards);
    RETAIN max_count;
    max_count = max(max_count, count);
    IF _n_ = _nobs THEN CALL SYMPUT('max_col', PUT(max_count, 8.));
    STOP;
RUN;

步骤3:动态拆分并填充列

利用数组动态生成WizardN列,循环提取匹配的姓名并填充:

DATA want;
    SET hogwarts;
    /* 根据最大列数定义数组 */
    ARRAY Wizard[&max_col] $64.;
    LENGTH temp_str $255;
    temp_str = Wizards;
    
    DO i = 1 TO dim(Wizard);
        /* 提取当前字符串中第一个匹配的姓名 */
        Wizard[i] = prxposn(prxparse(cats('/\s*(&regex)\s*/')), 1, temp_str);
        /* 移除已提取的姓名,压缩多余空格 */
        IF NOT missing(Wizard[i]) THEN DO;
            temp_str = prxchange(cats('s/\s*', quote(trim(Wizard[i]), "'"), '\s*/ /'), 1, temp_str);
            temp_str = strip(compress(temp_str, , 's'));
        END;
    END;
    
    DROP i temp_str;
RUN;

代码说明

  1. 正则模板:将所有姓名拼接为(姓名1|姓名2|姓名3)的形式,确保只匹配完整姓名,避免出现部分字符匹配的错误。
  2. 动态列数:先统计最大匹配数量,保证生成的数组能覆盖所有行的拆分需求。
  3. 顺序提取:每次提取当前字符串中第一个匹配的姓名,移除后继续处理剩余内容,严格保留原位置顺序。

内容的提问来源于stack exchange,提问作者askadum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:40:19