【问题标题】:Regex: Match patterns except with pattern preceding正则表达式:匹配模式,除了前面的模式
【发布时间】:2020-01-29 14:51:35
【问题描述】:

我正在尝试编写一个正则表达式来匹配某些模式,除了那些具有前面模式的模式。换句话说,给出以下句子:

Don't want to match paragraph 1.2.3.4 but this instead 5.6.7.8

我想匹配所有前面没有单词paragraphX.X.X.X,即它应该只匹配5.6.7.8。我当前的正则表达式似乎与 1.2.3.4 和 5.6.7.8 匹配。我已经切换了前瞻,但似乎与我的用例不匹配。

(?<!paragraph)(?:[\(\)0-9a-zA-Z]+\.)+[\(\)0-9a-zA-Z]+

我用 javascript 编码。

编辑:请注意 X.X.X.X 不固定为 4 Xs。它们的范围从 X.XX.X.X.X.X

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    您的模式匹配,因为“paragraph”与“paragraph[space]”不同。您的图案没有空格。你的文字可以。

    您可能希望将空格(可能是有条件的?)添加到您的lookbehind 中。因为你想匹配不同数量的X.X.X.X(你说过X.XX.X.X.X.X),所以我们还需要在lookbehind中包含X.

    const rex = /(?<!paragraph *(?:[\(\)0-9a-zA-Z]+\.)*)(?:[\(\)0-9a-zA-Z]+\.){1,4}[\(\)0-9a-zA-Z]/i;
    

    现场示例:

    function test(str) {
        const rex = /(?<!paragraph *(?:[\(\)0-9a-zA-Z]+\.)*)(?:[\(\)0-9a-zA-Z]+\.){1,4}[\(\)0-9a-zA-Z]/i;
        const match = rex.exec(str);
        console.log(match ? match[0] : "No match");
    }
    
    console.log("Testing four 'digits':");
    test("Don't want to match paragraph 1.2.3.4 but this instead 5.6.7.8 blah");
    
    console.log("Testing two 'digits':");
    test("Don't want to match paragraph 1.2.3.4 but this instead 5.6 blah");
    
    console.log("Testing two 'digits' again:");
    test("Don't want to match paragraph 1.2 but this instead 5.6 blah");
    
    console.log("Testing five 'digits' again:");
    test("Don't want to match paragraph 1.2 but this instead 5.6.7.8.9 blah");

    该表达式需要:

    • paragraph 后跟零个或多个空格可能后跟X. zer 或更多次在比赛前不是;和
    • X. 重复一到四次 ({1,4});和
    • X 紧跟在这三个后面

    X 在我的示例中是A-Z0-9,我已经使表达式不区分大小写,但您可以根据需要进行调整。


    请注意,最近才在 ES2018 中将lookbehind 添加到 JavaScript,因此支持需要最新的 JavaScript 环境。如果您需要回顾旧环境,您可以查看 Steven Levithan 的优秀 XRegex library

    另请注意,并非所有语言都支持像上面这样的可变长度后向查找(但 在 JavaScript 中支持...在最新的引擎中)。

    【讨论】:

    • 您好,感谢您的快速回答。抱歉,我可能没有更清楚。 {3} 可能无法很好地概括,因为在某些情况下X. 可能不会重复 3 次。它的范围从X.XX.X.X.X.X。如果我将{3} 更改为{1,}paragraph 之后的部分编号仍然会匹配。
    • 我将更新问题以概括编号。
    • @Koh - 啊,那会更复杂,并且可能涉及交替......
    • @Koh - 已更新以处理它。不需要交替,只是添加到后视。我又回到了你对 X 的原始定义。
    • 请注意并非所有浏览器都支持lookbehind。此外,许多语言不支持可变长度后视。
    【解决方案2】:

    如果你总是想匹配一个 4 项目组,你可以这样做:

    (?<!paragraph )([0-9]+.?){4}
    

    【讨论】:

      【解决方案3】:

      您可以迭代地构建正则表达式 -

      1. 忽略前面带有“段落”和空格的任何单词。
      2. 由于您的模式是固定的,它将由一个以句点分隔的四组数字组成,因此可以安全地假设该四组中的最小位数为 1。
      3. 在捕获组中捕获四倍数以供以后使用。

      测试正则表达式here

      const inputData = 'Don\'t want to match paragraph 1.2.3.4 but this instead 5.6.7.8 and 12.2.333.2';
      const re = /(?<!paragraph\s+)(\d{1,}\.\d{1,}\.\d{1,}\.\d{1,})/ig;
      
      const matchedGroups = inputData.matchAll(re);
      
      for (const matchedGroup of matchedGroups) {
      	console.log(matchedGroup);
      }

      【讨论】:

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