代码之家  ›  专栏  ›  技术社区  ›  Razor

正则表达式nongredy贪婪

  •  7
  • Razor  · 技术社区  · 16 年前

    我有以下文字

    tooooooooooooon
    

    根据我正在读的这本书,当 ? 在任何量词之后,它就变得不贪婪了。

    我的正则表达式 to*?n 仍在返回 tooooooooooooon .

    它应该会回来 ton 不是吗?

    你知道为什么吗?

    5 回复  |  直到 13 年前
        1
  •  46
  •   Gareth    16 年前

    正则表达式只能匹配实际存在的文本片段。

    因为子字符串“ton”在字符串中的任何位置都不存在,所以它不能是匹配的结果。匹配将只返回原始字符串的子字符串

    编辑:如果您使用下面的字符串,请加上一个'N'

    toooooooonoooooon
    

    此正则表达式(不指定“o”)。

    t.*n
    

    将匹配以下内容(在“n”之前尽可能多的字符)

    嘟嘟嘟嘟
    

    但是正则表达式

    t.*?n
    

    只匹配以下内容(在“n”之前尽可能少的字符)

    toooooooon
    
        2
  •  5
  •   Tomalak    16 年前

    正则表达式总是渴望匹配。

    你的表情是这样说的:

    A 't', followed by *as few as possible* 'o's, followed by a 'n'.
    

    这意味着所有必需的O都将被匹配,因为结尾处有一个“N”,而表达式急于到达。匹配所有的O是成功的唯一可能性。

        3
  •  4
  •   Vinko Vrsalovic    16 年前

    regexp尝试匹配其中的所有内容。因为要匹配的“o”不少于to o o o n中要匹配n的每个“o”,所以所有的都是匹配的。另外,因为您使用的是O*?而不是O+?您不需要O出席。

    示例,在Perl中

    $a = "toooooo";
    $b = "toooooon";
    
    if ($a =~ m/(to*?)/) {
            print $1,"\n";
    }
    if ($b =~ m/(to*?n)/) {
            print $1,"\n";
    }
    
    ~>perl ex.pl
    t
    toooooon
    
        4
  •  4
  •   Brad Gilbert    16 年前

    正则表达式总是尽其所能匹配。在这种情况下,唯一要做的就是通过让解析器回溯到 /o*?/ 节点。每件一次 'o' 在里面 "tooooon" . 而对于正常匹配,则需要 “O” S,尽可能,第一次通过。因为下一个要匹配的元素是 'n' ,这是不匹配的 “O” ,尝试使用最小匹配没有什么意义。实际上,当正常匹配失败时,需要很长时间才能失败。它必须回溯到 “O” 直到没有一个可以回溯过去。在这种情况下,我实际上会使用最大匹配 /to*+n/ . 这个 “O” 会尽一切努力,永远不会放弃。这将使它在失败时很快失败。

    最小重新成功:

    'toooooon' ~~ /to*?n/
    
     t  o  o  o  o  o  o  n       
    {t}                           match [t]
    [t]                           match [o] 0 times
    [t]<n>                        fail to match [n] -> retry [o]
    [t]{o}                        match [o] 1 times
    [t][o]<n>                     fail to match [n] -> retry [o]
    [t][o]{o}                     match [o] 2 times
    [t][o][o]<n>                  fail to match [n] -> retry [o]
    
    . . . .
    
    [t][o][o][o][o]{o}            match [o] 5 times
    [t][o][o][o][o][o]<n>         fail to match [n] -> retry [o]
    [t][o][o][o][o][o]{o}         match [o] 6 times
    [t][o][o][o][o][o][o]{n}      match [n]
    

    正常再续:

    (注:最大Re相似)

    'toooooon' ~~ /to*n/
    
     t  o  o  o  o  o  o  n       
    {t}                           match [t]
    [t]{o}{o}{o}{o}{o}{o}         match [o] 6 times
    [t][o][o][o][o][o][o]{n}      match [n]
    
    

    最小Re故障:

    'toooooo' ~~ /to*?n/
    
     t  o  o  o  o  o  o
    
    . . . .
    
    . . . .
    
    [t][o][o][o][o]{o}            match [o] 5 times
    [t][o][o][o][o][o]<n>         fail to match [n] -> retry [o]
    [t][o][o][o][o][o]{o}         match [o] 6 times
    [t][o][o][o][o][o][o]<n>      fail to match [n] -> retry [o]
    [t][o][o][o][o][o][o]<o>      fail to match [o] 7 times -> match failed
    

    正常RE故障:

    'toooooo' ~~ /to*n/
    
     t  o  o  o  o  o  o       
    {t}                           match [t]
    [t]{o}{o}{o}{o}{o}{o}         match [o] 6 times
    [t][o][o][o][o][o][o]<n>      fail to match [n] -> retry [o]
    [t][o][o][o][o][o]            match [o] 5 times
    [t][o][o][o][o][o]<n>         fail to match [n] -> retry [o]
    
    . . . .
    
    [t][o]                        match [o] 1 times
    [t][o]<o>                     fail to match [n] -> retry [o]
    [t]                           match [o] 0 times
    [t]<n>                        fail to match [n] -> match failed
    

    最大Re失效:

    'toooooo' ~~ /to*+n/
    
     t  o  o  o  o  o  o
    {t}                           match [t]
    [t]{o}{o}{o}{o}{o}{o}         match [o] 6 times
    [t][o][o][o][o][o][o]<n>      fail to match [n] -> match failed
    
        5
  •  2
  •   Hank    16 年前

    您正在搜索的字符串(Haystack原样)不包含子字符串“ton”。

    但是它包含子字符串“toooooooooooooooooon”。