Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex awk中多字符分隔符的非贪婪正则表达式匹配_Regex_Awk - Fatal编程技术网

Regex 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”之间有奇数个字符。如果

考虑字符串“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”
之间有奇数个字符。如果我将
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
}