【问题标题】:Regex to discard an entire capture if it's immediately preceded by a specific character正则表达式丢弃整个捕获,如果它紧跟在特定字符之前
【发布时间】:2023-03-22 16:47:01
【问题描述】:

给定以下文本:

somerandomtext06251/750/somerandomtext/21399/10 79/20 8301

如何提取 06251/750、79/20、8301 并忽略 21399/10?

一般规则:

  • 在随机字符串中匹配每组至少 2 位数字,后跟可选的 /,再后跟至少 2 位数字;对数字贪婪(尽可能多)
  • 如果前面紧跟 / 则忽略完整匹配

我从以下匹配模式开始:

 (?<invnr>\d{2,}/?\d{2,})

总的来说,它可以工作,但它只有一个问题:它也需要 21399/10。所以,我在后面添加了一个否定的lookbehind:

 (?<!/)(?<invnr>\d{2,}/?\d{2,})

现在它忽略了 21399/10 的第一个数字(因为它前面是 /),但它仍然捕获了所有后续字符,即 1399/10。但我需要完全跳过 21399/10。

我如何进行后视以删除整个匹配并跳到下一个而不是只跳过一个数字?

【问题讨论】:

    标签: .net regex regex-group negative-lookbehind


    【解决方案1】:

    您可以在否定的lookbehind 中添加一个数字模式(通过使用字符类[/\d] 将它与/ 组合)以确保如果紧跟在一个数字之后就不会发生匹配:

    (?<![/\d])\d{2,}(?:/\d{2,})?
    

    regex demo

    详情

    • (?&lt;![/\d]) - 如果有 / 或紧邻当前位置左侧的数字,则匹配失败
    • \d{2,} - 两位或多位数字
    • (?:/\d{2,})? - / 和两个或多个数字的可选序列。

    如果您需要确保只匹配 ASCII 数字,请将 RegexOptions.ECMAScript option 传递给 .NET 方法内的正则表达式编译器,或者使用 [0-9] 而不是 \d

    请注意,您的 \d{2,}/?\d{2,} 有点偏离,因为它不匹配 2 位或 3 位数字序列,仅匹配 4 位以上的数字序列。

    【讨论】:

    • 谢谢,添加\d 到负面的后视是关键。关于不匹配 2 位或 3 位数字序列 - 这是故意的,因为我需要至少 4 位数字,要么不间断,要么用可选的 / 分成两组。
    • @JustAMartin 好吧,您的 至少 2 位数字后跟可选的 / 并且后跟另一个至少 2 位数字 要求有所不同,但适合您自己 :) 主要思想是什么时候你写的pattern是后面的未知长度匹配pattern应该不能在同一个位置匹配,而你的x{2,}/?x{2,}可以。
    • 在该句子中,只有 / 表示可选,但两边的 2 个数字是强制性的,因此至少有 4 个强制性数字。是的,有点令人困惑,我应该用不同的措辞:)
    【解决方案2】:

    尽管不如 Wiktor's answer 强大,但您可以选择在模式之前提供允许的字符的白名单:

    (?<=^|[ a-z])[0-9]{2,}(?:\/[0-9]{2,})?
    

    Regex demo

    【讨论】:

      【解决方案3】:

      另一种方法是匹配以/ 开头的模式,并使用替换| 捕获那些不在组() 中的模式。

      /[0-9]{2,}(?:/[0-9]{2,})?|(?<invnr>[0-9]+(?:/[0-9]{2,})?)
      
      • /[0-9]{2,}(?:/[0-9]{2,})? 将模式与前导 / 匹配
      • |或者
      • (?&lt;invnr&gt;[0-9]+(?:/[0-9]{2,})?)捕获组invnr中的模式

      .NET Regex demo(点击表格标签查看分组值)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-17
        • 1970-01-01
        • 2021-11-15
        相关资源
        最近更新 更多