Regex awk中多字符分隔符的非贪婪正则表达式匹配
考虑字符串“ab1ba2ab3ba”。如何以非贪婪的方式(在awk中)匹配Regex awk中多字符分隔符的非贪婪正则表达式匹配,regex,awk,Regex,Awk,考虑字符串“ab1ba2ab3ba”。如何以非贪婪的方式(在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”
和“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”
之间有奇数个字符。如果我将str
替换为“AB 11 BA 22 AB 33 BA”
,正则表达式似乎可以工作。合并两个否定字符类,并从第二个替换中删除[^A]
:
regex = "AB([^AB]|B|[^B]A)*BA"
这个正则表达式在字符串ABABA
上失败,但是-不确定这是否是一个问题
说明:
由于在替换中匹配
A
的唯一方法是匹配前面的B
之外的字符,因此我们可以安全地使用简单的B
作为替换之一。另一个答案并没有真正回答:如何不贪婪地匹配?
看来这件事不能在(G)AWK中完成。手册上说:
awk(和POSIX)正则表达式始终匹配最左边、最长的
可以匹配的输入字符序列
整个手册中没有“贪婪”和“懒惰”这两个词。它提到了扩展正则表达式,但是。所以…不,不行 对于一般表达式,我将其用作非贪婪匹配:
function smatch(s, r) {
if (match(s, r)) {
m = RSTART
do {
n = RLENGTH
} while (match(substr(s, m, n - 1), r))
RSTART = m
RLENGTH = n
return RSTART
} else return 0
}
smatch
的行为类似于match
,返回:
在s
中正则表达式r
出现的位置,如果没有出现,则为0。变量RSTART
和RLENGTH
设置为匹配字符串的位置和长度
仍然有点困惑:)为什么
AB([^AB]|[^B]a)*BA
匹配ABBBA
,而它不匹配abababa
?@HåkonHægland:regex不匹配ABBBA
…我的匹配是因为在替换中有一个B
。我想知道为什么你的regex与我从DFA派生的regex不同。结果发现它正在匹配中。顺便说一下,正确的答案是AB([^B]|B+[^AB])*B*BA
。
function smatch(s, r) {
if (match(s, r)) {
m = RSTART
do {
n = RLENGTH
} while (match(substr(s, m, n - 1), r))
RSTART = m
RLENGTH = n
return RSTART
} else return 0
}