如何在SAS中动态扫描并转换字符串:程序名转表编号
在SAS中实现动态转换SAS程序名为表编号
这是个很常见的字符串处理需求,针对你给出的格式(f-数字段1-数字段2-...-数字段N-后缀),我给你分享两种实用的实现方式,都能动态适配不同数量的数字段:
方法一:正则表达式快速提取(推荐)
利用SAS的PRXCHANGE函数结合正则表达式,可以一步提取出所有连续的数字段,再替换分隔符即可,代码非常简洁:
data want; set have; /* 第一步:提取f-开头后所有连续的数字段(直到遇到非数字后缀) */ temp_str = prxchange('s/^f-((?:\d+-)*\d+).*$/\1/', 1, prog_name); /* 第二步:把数字段之间的"-"替换为"." */ table_id = tranwrd(temp_str, '-', '.'); drop temp_str; run;
代码解释:
- 正则表达式
^f-((?:\d+-)*\d+).*$的作用:^f-:匹配字符串开头的固定前缀f-(?:\d+-)*\d+:匹配一个或多个数字+短横线的重复组合,最后以纯数字结尾(非捕获组(?:...)用来分组但不单独捕获).*$:匹配后缀部分的所有内容- 替换为
\1就是保留捕获到的所有数字段部分
TRANWRD函数负责把数字段之间的-替换成目标格式的.
测试效果:
- 输入
f-2-2-7-5-vcb→ 输出2.2.7.5 - 输入
f-2-2-12-1-2-hbd87q→ 输出2.2.12.1.2 - 输入
f-3-4-5-6(无后缀)→ 输出3.4.5.6
方法二:循环扫描+纯数字判断(灵活性更高)
如果你的场景可能存在中间夹杂非数字段的情况,这种方法可以精准筛选出所有纯数字段,跳过非数字内容:
data want; set have; length table_id $ 100; /* 根据实际需求调整长度 */ table_id = ""; /* 循环扫描字符串的每个分隔段,从第2段开始(跳过开头的"f") */ do i = 2 by 1 while(scan(prog_name, i, '-') ne ""); segment = scan(prog_name, i, '-'); /* 判断当前段是否为纯数字(用正则匹配) */ if prxmatch('/^\d+$/', segment) then do; /* 用CATX自动添加分隔符,避免开头或结尾出现多余的点 */ table_id = catx('.', table_id, segment); end; else do; /* 遇到非数字段就停止循环(适配后缀在最后的场景) */ leave; end; end; drop i segment; run;
代码解释:
SCAN函数按-分割字符串,从第2段开始遍历(跳过第一个f)PRXMATCH('/^\d+$/', segment)判断当前段是否是纯数字(从开头到结尾都是数字)CATX函数会自动用.连接纯数字段,且不会产生多余的分隔符- 遇到非数字段时用
leave停止循环,符合你给出的后缀在最后的格式特点
测试效果:
- 输入
f-2-2-7-5-vcb→ 输出2.2.7.5 - 输入
f-2-2-12-1-2-hbd87q→ 输出2.2.12.1.2 - 输入
f-2-a-3-4-x(中间有非数字段)→ 输出2(只保留第一个纯数字段)
内容的提问来源于stack exchange,提问作者johnww
相关产品推荐
相关产品推荐

