【问题标题】:Conflicts on having the same group at the start and at the end在开始和结束时具有相同组的冲突
【发布时间】:2019-05-08 04:39:33
【问题描述】:

我有一个应该捕获的正则表达式:

[=foo]
[="foo"]
[='foo']

开头和结尾必须相同,所以我要捕获引号并在末尾用 \1 调用它。它用来接受的问号也没有引号:

\[=(['\"]?)(.+)\1\]

如果我在一行上尝试它工作得很好,但是当我尝试写其他任何东西并调用一个闭括号时,它会匹配到那个括号。一些行为示例:https://regex101.com/r/4qYzyS/1

有人有解决办法吗?匹配我想要的 3 种模式而不会发生冲突?谢谢。

【问题讨论】:

    标签: python regex pcre


    【解决方案1】:

    使点不贪心,即使用(.+?)。此外,您可能想要关闭第二个捕获组,或者可能只是将其完全删除。例如。以下模式似乎有效:

    \[=([\"']?).+?\1\]
    

    Demo

    这是一个示例 Python 脚本:

    input = "[=\"foo\"]\n[=\"Lorem ipsum\"]\n\n[=foo]Lorem ipsum]";
    for match in re.finditer(r"\[=([\"']?).+?\1\]", input):
        print match.group(0)
    
    [="foo"]
    [="Lorem ipsum"]
    [=foo]
    

    【讨论】:

      【解决方案2】:

      你可以简单地使用这个表达式:

      (\[=)(.+)(\])
      

      Demo

      如果您希望添加边界而不是使用(.+),则可能需要使用表达式并添加[] 之间可能存在的任何字符,也许是similar to

      (\[=)([A-z\s\x22]+)(\])
      

      图表

      此图显示了第二个表达式的工作原理,您可以在此 link 中可视化其他表达式:

      代码

      这段代码展示了表达式在 Python 中的工作方式:

      # -*- coding: UTF-8 -*-
      import re
      
      string = "[=foo]Lorem ipsum] with anything else that you wish"
      expression = r'((\[=)([A-z\s\x22]+)(\]))'
      match = re.search(expression, string)
      if match:
          print("YAAAY! \"" + match.group(1) + "\" is a match ??? ")
      else: 
          print('? Sorry! No matches! Something is not right! Call 911 ?')
      

      输出

      YAAAY! "[=foo]Lorem ipsum]" is a match ???
      

      性能测试

      此 JavaScript sn-p 使用简单的 100 万次 for 循环显示表达式的性能。

      repeat = 1000000;
      start = Date.now();
      
      for (var i = repeat; i >= 0; i--) {
      	var string = "[=foo]Lorem ipsum] with anything else that you wish";
      	var regex = /((\[=)([A-z\s\x22]+)(\]))(.*)/g;
      	var match = string.replace(regex, "$1");
      }
      
      end = Date.now() - start;
      console.log("YAAAY! \"" + match + "\" is a match ??? ");
      console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");

      【讨论】:

      • 我喜欢@Emma 的演示文稿。干杯。
      【解决方案3】:

      如果您将(.+) 设为非贪婪的(.+?),您将防止吞下字符串的其余部分:

      \[=([\"']?)(.+?)\1\]/
                    ^
      

      【讨论】:

      • 非贪婪正则表达式不会按照他想要的方式匹配 OP 的第三个样本。
      • 怎么样?我看到一个完整的字符串匹配。
      • 检查这个字符串[=foo]Lorem ipsum]
      • 对我来说似乎很好,它与指定的 OP 匹配 [=foo],不是吗?
      • 我认为 OP 想要匹配整行,直到最后一个 ] 这就是他使用 .+ 贪婪量词的原因。
      【解决方案4】:

      您的正则表达式工作正常,它与第二行匹配的原因是,您启用了DOTALL 模式,因为. 也匹配换行符。只需取消选中s 模式即可禁用DOTALL 模式,您将获得预期的结果。

      Regex Demo after disabling DOTALL mode

      另外,在您的第三个示例中,我不确定您是否希望您的正则表达式完全匹配,但如果您打算只匹配 [=foo] 而不是 [=foo]Lorem ipsum],那么您应该使用 @987654331 @ 而不是 .+ 在你的正则表达式中。

      此外,如果您的字符串被"' 或两边都没有包围,您似乎想要匹配您的字符串,那么您还应该在否定字符中包含"'类,因此您的正则表达式不应与 [="foo] 这样的输入匹配。总的来说,您应该使用的正确正则表达式是这样的,

      Regex that you should be using precisely

      【讨论】:

        猜你喜欢
        • 2021-08-11
        • 1970-01-01
        • 2019-02-14
        • 2013-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多