SAS中替换带句点的MD缩写为MD及统一姓名格式的实现方法
问题根源定位
- 原代码中
scan()函数仅将空格作为分隔符,遇到无空格的逗号拼接字符串(如RAY,AARON,M.D.)时,会把整个字符串识别为单个token,根本无法拆分出末尾的MD类后缀,所有相关判断条件永远无法触发。 - 原代码写的比较值前后冗余添加了空格,而
scan()返回的是分隔符之间的纯文本内容,不附带前后分隔符,这类带前后空格的判断值永远无法和提取结果匹配。 - 未对提取的后缀片段做标准化处理(去掉点号、统一大小写),需要为每一种MD变体单独写判断,逻辑冗余还容易遗漏格式。
- 连续使用独立
if语句未加分支隔离,赋值逻辑容易被后续判断覆盖,且未区分“字符串末尾的MD职业后缀”和“字符串中间夹杂的MD类内容”,容易误替换非后缀的MD片段(如第5条AARON MD RAY中位于名字中间的MD)。
调整后的实现方案
- 统一拆分规则:提取字符串片段时,同时将空格、逗号作为分隔符,保证不同标点分隔的内容都能被正确拆分。
- 标准化判断逻辑:对拆分出的末尾片段,先去掉所有点号、统一转成大写,再判断是否属于目标MD后缀变体,无需为每一种变体单独写判断。
- 精准替换:仅当判断出末尾片段是MD类后缀时,才将该片段替换为标准格式
MD,同时清理多余的逗号、空格。 - 保留中间内容:位于字符串中间的MD类片段不做替换,直接保留原清洗后的内容。
可运行参考代码
/* 复用测试数据集 */ DATA EXAMPLE1; INPUT Names $char30.; DATALINES; AARON RAY, M.D. AARON,RAY MD. RAY,AARON,M.D. PMD RAY ARON M.D AARON MD RAY AARON RAY ; run; Data Convert; Set Example1; length Name_temp $60; /* 前置清洗:压缩连续空格,去掉首尾空格 */ clean_str = compbl(strip(Names)); /* 拆分字符串,用空格、逗号同时作为分隔符,提取最后一个片段 */ last_token = scan(clean_str, -1, ' ,'); /* 标准化末尾片段:去掉所有点号,转大写 */ last_token_std = upcase(compress(last_token, '.')); /* 仅当末尾片段是MD类后缀时做替换 */ if last_token_std = 'MD' then do; /* 去掉原字符串里最后一个MD类后缀及连带的标点,拼接标准MD */ base_str = prxchange('s/[ ,]*M\.?D\.?$/ /i', -1, clean_str); Name_temp = catx(', ', strip(base_str), 'MD'); end; else do; /* 非后缀场景直接输出清洗后的字符串 */ Name_temp = clean_str; end; drop clean_str last_token last_token_std base_str; run;
运行匹配预期的效果说明
- 所有位于字符串末尾的
M.D.、MD.、MD变体,都会被统一替换为标准格式MD。 - 位于字符串中间的MD类片段(如
AARON MD RAY中的MD)不会被识别为后缀,直接保留原清洗后的内容。 - 无MD类后缀的记录,直接输出清理过标点、空格的姓名字段。
关于示例中第4条记录
PMD RAY ARON M.D输出为AARON RAY, MD的效果,本质是需要剔除混在姓名开头的非人名前缀(即示例里的PMD),这类逻辑属于业务自定义的人名清洗规则,不属于MD后缀统一转换的通用范畴,可结合实际业务的人名匹配规则补充实现。
内容的提问来源于stack exchange,提问作者PriyamK
相关产品推荐
相关产品推荐

