美文网首页
正则表达式的贪婪模式和非贪婪模式

正则表达式的贪婪模式和非贪婪模式

作者: 王小二黑 | 来源:发表于2019-07-17 18:40 被阅读0次

    一直听说过正则表达式存在贪婪和非贪婪模式,大概就是最少匹配和最多匹配的区别,看到的例子大多是下面这个例子
    源字符串: aabab
    贪婪模式串: a.b
    非贪婪模式串: a.
    ?b
    贪婪模式结果: aabab
    非贪婪模式结果: aab

    上面这个例子虽然简单,但是感觉代表性不强,实现今天在解析postgres 逻辑复制的输入时, 刚好碰到一个例子,特来记录下:
    输出如下:
    table public.t_02: UPDATE: id[integer]:1 name[text]:'name[text]:' create_date[date]:'2020-11-01' bbb[bytea]:null

    在通过split之后, 得到待处理的字符串,。
    源字符串:name[text]:'name[text]:'
    其中name是字段名,text是字符类型, 'name[text]:'是字段的值,现在要通过正则表达式来提取字段名,类型以及字段值。
    []中包含的是类型, :后面的是字段值,因此很自然的想到这个模式串:
    ^(.*)\[(.*)\]:(.*)$
    代码如下:

    parttern = `^(.*)\[(.*)\]:(.*)$` 
    reg = regexp.MustCompile(parttern)
    result = reg.FindStringSubmatch(v)
    col := Column{
                Name:  result[1],
                Type:  result[2],
                Value: result[3],
            }
    

    匹配结果分为三组,

    1. name[text]:'name
    2. text
    3. '
    

    完全不是我想要的结果 -_-!!!
    出现问题的原因是值里面也出现name[type]:value的模式,所以刚好踩到了贪婪模式的坑。
    这里其实golang给了一个迷惑性的说法, regexp.MustCompile是最左、最短匹配, 而regexp.MustCompilePOSIX是最左、最长匹配, 因此,我还以为MustCompile已经是非贪婪匹配了。不过好在golang提供了匹配标志(?U)来表示非贪婪匹配,修改之后的代码如下:

    parttern = `^(?U)(.*)\[(.*)\]:(.*)$`  // (?U)非贪婪模式
    reg = regexp.MustCompile(parttern)
    result = reg.FindStringSubmatch(v)
    col := Column{
                Name:  result[1],
                Type:  result[2],
                Value: result[3],
            }
    

    匹配结果:

    1. name
    2. text
    3. 'name[text]:'
    

    相关文章

      网友评论

          本文标题:正则表达式的贪婪模式和非贪婪模式

          本文链接:https://www.haomeiwen.com/subject/txpclctx.html