使用expr match匹配行首字符串时出现正则兼容性警告问题排查
行首字符串匹配的expr错误原因分析
示例文本
a.z //match # a.z bc.x //match #bc.x c.z bc.z //match
我的代码
while read p; do if [ $(expr match "$p" '^a\..*|^bc\..*') ]; then echo $p fi done <file.txt
运行错误警告
expr: warning: 'a..*|bc..*': using '^' as the first character
of a basic regular expression is not portable; it is ignored
错误原因解析
expr match的默认匹配逻辑:expr match的语法本身就是强制从字符串开头匹配正则,你手动添加的^完全多余。而expr使用的是基本正则表达式(BRE)规范,^作为正则首字符属于非移植性写法,部分环境会直接忽略它,这就是警告的直接来源。分支匹配的语法错误:BRE规范里,
|是普通字符,不具备“或”分支的功能,要实现分支必须转义为\|。你当前的正则^a\..*|^bc\..*会被解析成“匹配^a.开头的任意字符,再匹配一个|,接着匹配^bc.开头的任意字符”,完全达不到你想要的“匹配以a.或bc.开头”的需求。未覆盖前置空格场景:从示例来看你需要匹配行首带空格的行(比如
bc.z //match),但当前正则完全没考虑这种情况,就算解决前两个问题,也无法匹配这类行。
修正思路(可选)
改用bash内置条件判断,写法更简洁且兼容性更好:
while read -r p; do if [[ $p =~ ^[[:space:]]*(a\.|bc\.) ]]; then echo "$p" fi done <file.txt
这里^[[:space:]]*匹配行首任意空格,(a\.|bc\.)实现分支匹配,完全覆盖你的需求。
内容的提问来源于stack exchange,提问作者Dinamo
相关产品推荐
相关产品推荐

