Awk中“illegal primary”含义解析及正则报错咨询
解析Awk中的"illegal primary"错误及你的问题解决办法
什么是Awk里的"illegal primary"?
简单来说,这个错误表示你写的正则表达式里有Awk的正则引擎不认识、不支持的语法元素。这里的"primary"指的是正则表达式里的基础语法单元——Awk默认遵循POSIX标准的正则(BRE或ERE),很多Perl兼容正则(PCRE)里的高级特性对它来说都是"非法"的。
你的具体报错原因
看你写的正则/(?<=>)(.*?)(?=<):
(?<=>)是正向回顾后发断言(lookbehind),用来匹配前面是>的位置(?=<)是正向前瞻断言(lookahead),用来匹配后面是<的位置
这些都是PCRE独有的环视(lookaround)特性,标准Awk(包括大多数默认的Awk实现,比如nawk、mawk,甚至GNU Awk默认模式)都不支持这种语法。Awk看到这些(?...)的结构时,无法识别它们是合法的正则单元,所以就抛出了"illegal primary"的错误。
怎么解决你的需求?
你想要的应该是提取>和<之间的内容吧?不用环视也能轻松实现,而且兼容性更好:
方法1:用GNU Awk的捕获组数组(推荐,简洁)
GNU Awk(gawk)支持match函数的第三个参数,用来存储捕获组的内容:
match($0, />(.*)</, match_arr) # 捕获组1的内容就是>和<之间的文本 print match_arr[1]
方法2:兼容POSIX Awk的写法(适用于所有Awk版本)
如果你的环境只能用标准POSIX Awk,可以用RSTART和RLENGTH变量来截取:
if (match($0, />(.*)</)) { # RSTART是匹配的起始位置,+1跳过>;RLENGTH是整个匹配长度,-2去掉>和< content = substr($0, RSTART + 1, RLENGTH - 2) print content }
方法3:用支持PCRE的Awk版本(不推荐,兼容性差)
如果你非要用环视语法,可以用带PCRE扩展的GNU Awk:
- 确保你的gawk编译时启用了PCRE支持
- 加载PCRE扩展并使用
pcre_match函数:
@load "pcre" if (pcre_match($0, /(?<=>)(.*?)(?=<)/, match_arr)) { print match_arr[1] }
不过这个方法依赖特定的gawk版本和编译选项,通用性不强。
内容的提问来源于stack exchange,提问作者303
相关产品推荐
相关产品推荐

