【问题标题】:Unmatched [ in regex, despite being escaped在正则表达式中不匹配 [,尽管被转义
【发布时间】:2015-03-22 21:32:15
【问题描述】:

尝试测试perl的位置函数和解析能力。我有一个正则表达式,我认为它是正确的,但是 perl 告诉我我有一个无与伦比的 [,但对我来说它看起来已经逃脱了。

正则表达式中不匹配的 [;由

谁能澄清为什么我会从以下代码中收到该消息?

my $string = "one, [two] , [three], and [four].";

pos($string) = 0;
while (my $string =~ m{\G.*\[([^\]+)\]}cg)
{
    my $value = $1;
    print "Found value $value .\n";
};

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    否定字符类没有终止。

    你在哪里

    [^\]+    # One or more characters that aren't «]», «+», ...
    

    你应该有

    [^\]]+   # One or more characters that aren't «]»
    

    我什至会使用

    [^[\]]*  # Zero or more characters that aren't «[» or «]»
    

    【讨论】:

      【解决方案2】:

      错误是由于字符类不完整...

      \G.*\[([^\] +)\]
                 ^
      

      要解决这个问题,你需要添加一个右括号来完成这个类。

      \G.*\[([^\]]+)\]
                 ^
      

      我提出以下建议,同时将 + 更改为 * 以匹配“零个或多个”。

      [^]]*
      

      【讨论】:

        【解决方案3】:

        你只逃脱了 4 人中的 3 人。

        m{\G.*\[([^\]+)\]}cg)
               ^    ^   ^
                 ^ - not escaped
        

        【讨论】:

        • 四个中只有三个应该被转义。问题是缺少]
        【解决方案4】:

        解释问题的正则表达式:

        m{\G.*\[([^\]+)\]}cg
        

        这个正则表达式是一个转义的 perl 正则表达式。 未转义的正则表达式是:\G.*\[([^\]+)\]

        正则表达式:\G.*\[([^\]+)\] 确实:

        • \G ... 断言该位置在上一个匹配项的末尾,或字符串的开头。
        • .* ... 匹配任何不是换行符的字符,介于零次和无限次之间。 (贪婪)
        • \[ ... 匹配字符 [

        现在无法处理正则表达式,有一个左括号而没有右括号。
        这是因为在左括号( 之后开始了一个字符类[,它需要在右括号) 之前关闭。
        尽管有一个\],但这是一个转义的],因此不是字符类的右括号。
        所以正则表达式中的) 是打开的字符类的一部分。
        由于最后一个] 也被转义,因此捕获组和字符类都没有关闭。

        在 Perl 正则表达式中,] 不需要转义。
        字符类的结尾不能转义。

        如果\[([^\]+)\] 旨在匹配[] 之间的所有字符并将其值捕获到捕获组1 中,则更正部分为:\[([^\]]+)\] 或更短的\[([^]]+)]

        所以最接近的工作正则表达式是:

        \G.*\[([^\]]+)\]
        

        并且可以缩短为

        \G.*\[([^]]+)]
        

        如果你想匹配twothreefour

        m/\[([^]]+)]/
        

        【讨论】:

        • 您能否详细说明为什么 OP 首先会出现错误?这似乎是主要问题,而不仅仅是正确的正则表达式
        【解决方案5】:

        您可能会发现在正则表达式中添加空格以使其更具可读性可以帮助您了解正在发生的事情。另外你有太多的“我的 $string” :-)

        my $string = "one, [two] , [three], and [four].";
        
        while ($string =~ m{
                \G.*
                \[
                    (  [^\]]+  )
                \]
            }cgx)
        {
            my $value = $1;
            print "Found value $value .\n";
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多