【问题标题】:My regex is matching too much. How do I make it stop? [duplicate]我的正则表达式匹配太多。我如何让它停止? [复制]
【发布时间】:2017-08-28 03:53:19
【问题描述】:

我有这个又大又丑的字符串:

J0000000: Transaction A0001401 started on 8/22/2008 9:49:29 AM
J0000010: Project name: E:\foo.pf
J0000011: Job name: MBiek Direct Mail Test
J0000020: Document 1 - Completed successfully

我正在尝试使用正则表达式从中提取片段。在这种情况下,我想获取 Project Name 之后的所有内容,直到它显示 J0000011: 的部分(11 每次都会是不同的数字)。

这是我一直在玩的正则表达式:

Project name:\s+(.*)\s+J[0-9]{7}:

问题是它直到最后碰到 J0000020: 才会停止。

如何使正则表达式在第一次出现 J[0-9]{7} 时停止?

【问题讨论】:

  • 项目名称:[^\n]*\n(J[0-9]{7})

标签: regex


【解决方案1】:

通过在 .* 后面添加“?”使 .* 不贪婪:

Project name:\s+(.*?)\s+J[0-9]{7}:

【讨论】:

    【解决方案2】:

    在这里使用非贪婪量词可能是最好的解决方案,也因为它比贪婪替代方案更有效:贪婪匹配通常会尽可能远(这里,直到文本结尾!)然后回溯一个接一个的字符来尝试匹配后面的部分。

    但是,请考虑改用否定字符类:

    Project name:\s+(\S*)\s+J[0-9]{7}:
    

    \S 表示“除了空格之外的所有内容,这正是您想要的。

    【讨论】:

    • 如果可以实现,贪婪的负(或正)字符类通常会比惰性量词表现得更好。懒惰要求引擎逐个字符向前跟踪,检查每次遵循的模式,直到匹配;贪婪的字符类可以盲目地重复所需的字符,这可以快得多。因此,您可能会考虑为否定字符类制定更强有力的案例,因为这是贪婪与懒惰的规范。
    【解决方案3】:

    好吧,".*" 是一个贪婪的选择器。您可以通过使用".*?" 使其不贪婪。当使用后一种构造时,正则表达式引擎将在每一步将文本匹配到"." 中,尝试匹配".*?" 之后的任何内容。这意味着,如果".*?" 之后没有任何内容,则它不会匹配任何内容。

    这是我使用的。 s 包含您的原始字符串。此代码是 .NET 特定的,但大多数正则表达式都有类似的内容。

    string m = Regex.Match(s, @"Project name: (?<name>.*?) J\d+").Groups["name"].Value;
    

    【讨论】:

      【解决方案4】:

      我还建议您使用“Expresso”来试验正则表达式 - 它是一个用于正则表达式编辑和测试的出色(免费)实用程序。

      它的一个优点是它的 UI 公开了许多不熟悉 regex 的人可能不熟悉的 regex 功能,以方便他们学习这些新概念。

      例如,当使用 UI 构建正则表达式并选择“*”时,您可以选中“尽可能少”复选框并查看生成的正则表达式,并测试其行为,即使您以前不熟悉非贪婪的表达方式。

      可在他们的网站上下载: http://www.ultrapico.com/Expresso.htm

      快速下载: http://www.ultrapico.com/ExpressoDownload.htm

      【讨论】:

      • 已经有一些很棒的网站了。我宁愿访问书签也不愿在我的计算机上安装其他程序。
      【解决方案5】:

      (项目名称:\s+[AZ]:(?:\\w+)+.[a-zA-Z]+\s+J[0-9]{7})(?=:)

      这对你有用。

      添加 (?:\\w+)+.[a-zA-Z]+ 将比 .* 更具限制性

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多