非贪婪的正则表达式匹配awk中的多字符分隔符

时间:2013-12-26 11:22:28

标签: regex awk

考虑字符串"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"之间存在奇数个字符。如果我将str替换为"AB 11 BA 22 AB 33 BA",则正则表达式似乎有用..

2 个答案:

答案 0 :(得分:5)

合并你的两个否定字符类并从第二个替换中删除[^A]

regex = "AB([^AB]|B|[^B]A)*BA"

这个正则表达式在字符串ABABA上失败了 - 但不确定这是否有问题。

<强>说明:

AB       # Match AB
(        # Group 1 (could also be non-capturing)
 [^AB]   # Match any character except A or B
|        # or
 B       # Match B
|        # or
 [^B]A   # Match any character except B, then A
)*       # Repeat as needed
BA       # Match BA

由于在替换中匹配A的唯一方法是匹配除B之前的字符,我们可以安全地使用简单B作为替代方法之一。< / p>

答案 1 :(得分:0)

对于一般表达式,我将其用作非贪婪的匹配:

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。变量RSTARTRLENGTH设置为匹配字符串的位置和长度。