sed启用扩展正则后无法匹配\w进行替换的问题咨询
问题
我有字符串90d_ASD_A98CAWd9A_WF8,希望捕获并移除其中的\w字符组(\w可匹配大小写字母及下划线)。但即使启用sed的扩展正则选项-E,执行命令:
echo "90d_ASD_A98CAWd9A_WF8" | sed -E s/"[\w]+"//g
后,原字符串无任何变化;而使用显式字符范围[A-Za-z_]+的对应命令,却能得到预期结果909898。请问我对\w的使用是否有误?问题出在哪里?
解答
问题核心是sed的正则语法和你预期的PCRE(Perl兼容正则)不一致,具体原因如下:
\w不属于POSIX标准正则范畴
sed默认遵循POSIX的基础正则(BRE)或扩展正则(ERE,通过-E启用),这两种规范里都没有定义\w这个简写字符组。\w是Perl、Python等语言使用的PCRE语法,sed原生不支持。- 字符类
[]内的语法限制
即便部分GNU sed版本在非字符类场景下可能兼容\w,但在字符类[]内部,POSIX正则只允许显式字符范围、单个字符或预定义POSIX字符类(如[:alpha:]、[:alnum:]),完全不识别\w这种简写。你写的[\w]+会被sed解析为匹配字符\或w,而原字符串里没有这两个字符,因此替换完全不生效。 - 显式字符范围生效的原因
[A-Za-z_]+是POSIX正则支持的显式字符范围,sed能正确识别并匹配大小写字母和下划线,所以能得到预期结果。
如果想在sed里实现类似\w的匹配效果,可以用POSIX预定义字符类组合:[[:alnum:]_]([:alnum:]匹配字母和数字,加上下划线就等价于\w),对应的命令是:
echo "90d_ASD_A98CAWd9A_WF8" | sed -E s/"[[:alnum:]_]+"//g
内容的提问来源于stack exchange,提问作者UrbanCentral
相关产品推荐
相关产品推荐

