SAS正则仅移除首个条目末尾s,问题出在哪里?
问题根源
你遇到的问题主要来自两个点:
- SAS字符变量默认补空格:使用
input city $;未指定长度时,SAS默认字符变量长度为8,输入的短字符串(如askers、Londons)会自动在末尾补空格,导致实际存储的字符串末尾是空格而非s,正则表达式的s$(匹配末尾的s)无法命中。 - 非贪婪匹配的冗余:虽然
.*?非贪婪匹配本身不是直接诱因,但在存在末尾空格的情况下,会让正则匹配逻辑更复杂,加剧问题。
解决方法
方法1:指定字符变量长度,避免补空格
在输入数据时明确指定足够长的变量长度,确保存储的字符串没有多余空格:
Data test; input city $20.; /* 指定足够长的长度,避免自动补空格 */ datalines; arjepogs askers Londons ; run; data cities; set test; if prxmatch("/^(.*)s$/", city) then city=prxchange("s/^(.*)s$/$1/", -1, city); run;
方法2:正则匹配时兼容末尾空格
如果不想修改输入步骤,可以在正则中加入对末尾空格的处理,匹配s及之后的所有空格并移除:
data cities; set test; /* 匹配末尾的s,允许s后面有任意数量的空格 */ city=prxchange("s/s\s*$//", -1, city); run;
方法3:用SAS内置函数替代正则(更高效)
对于移除末尾单个s的需求,用SAS内置函数更简单直接,避免正则的复杂性:
data cities; set test; city_trimmed = trim(city); /* 先去除末尾空格 */ if substr(city_trimmed, length(city_trimmed)) = 's' then city = substr(city_trimmed, 1, length(city_trimmed)-1); run;
原代码仅第一个条目生效的原因
arjepogs刚好是8个字符,和默认变量长度一致,没有补空格,所以末尾的s能被/^(.*?)s$/匹配到;而askers、Londons长度小于8,末尾被补了空格,正则无法匹配到末尾的s,因此没有执行替换。
内容的提问来源于stack exchange,提问作者Magnus
相关产品推荐
相关产品推荐

