考虑字符串"AB 1 BA 2 AB 3 BA"
。如何以非贪婪的方式(在awk中)匹配"AB"
和"BA"
之间的内容?
我尝试了以下几点:
awk '
BEGIN {
str="AB 1 BA 2 AB 3 BA"
regex="AB([^B][^A]|B[^A]|[^B]A)*BA"
if (match(str,regex))
print substr(str,RSTART,RLENGTH)
}'
字符串
没有输出。我认为不匹配的原因是"AB"
和"BA"
之间有奇数个字符。如果我用"AB 11 BA 22 AB 33 BA"
替换str
,正则表达式似乎可以工作。
4条答案
按热度按时间bprjcwpo1#
合并两个取反的字符类,并从第二个替换中删除
[^A]
:字符串
这个正则表达式在字符串
ABABA
上失败,但是-不确定这是否是一个问题。说明:
型
由于在交替中匹配
A
的唯一方法是匹配B
之前的字符,因此我们可以安全地使用简单的B
作为替代方案之一。5cg8jx4n2#
另一个答案并没有真正回答:如何进行非贪婪匹配?看起来它不能在(G)AWK中完成。手册上是这么说的:
awk(和POSIX)正则表达式总是匹配最左边、最长的输入字符序列。
https://www.gnu.org/software/gawk/manual/gawk.html#Leftmost-Longest
整本手册都没有“贪婪”或“懒惰”的字眼。它提到了扩展正则表达式,但for greedy matching you'd need Perl-Compatible Regular Expressions。所以不行
hgncfbus3#
对于一般表达式,我使用以下内容作为非贪婪匹配:
字符串
smatch
的行为类似于match
,返回:s
中正则表达式r
出现的位置,如果没有,则为0。变量RSTART
和RLENGTH
被设置为匹配字符串的位置和长度。qij5mzcb4#
使用特殊文本(退格键或\x00或类似文本)标记字段,然后在gsub命令中包含字段拆分器以删除额外的字段拆分器。
字符串