如何简化正则表达式模式?

时间:2019-05-18 22:17:02

标签: regex vb.net regex-lookarounds regex-group regex-greedy

我在这里试图简化正则表达式。

我尝试对相同的表达式进行重复,但是当我尝试使用()*简化它时,由于无法检测到我想要的模式,因此无法正常工作。

这些是我的正则表达式:

(([\(]\w]{1,3}[\)])\s([\d]{1,3}[\?])([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]([\(][\w]{1,3}[\)])\s([\d]{1,3}[\?])([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]([\(][\w]{1,3}[\)])\s[0-9]{1,3}[\?]([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?])

整个模式:

3A 1?(1) 2?(2) 3?(a) 4?(4) 5?(a) 6?(ii) 7?
4 6?(1) 7?(2) 8?(a) 9?(4) 10?(a) 11?(ii) 12?  

这些是它将检测到的模式:

1?(1) 2?(2) 3?(a) 4?(4) 5?(a) 6?(ii) 7?

正则表达式将检测 第一条线,而无需 3A 。我该怎么办? 正则表达式最简单的就是\d+\?(?:\([\da-z]+\))?,现在我该如何将其放在仅检测第一行的方式中?谢谢你们。

3 个答案:

答案 0 :(得分:1)

也许,如果可以的话,在这里我们可以用另一种方式简化它。例如,我们可能有三种模式,我们可以使用三个捕获组来捕获它:开始,结束和中间组,可能类似于:

(?:^\w+\s)|(\d\?\(\w+\)\s)|(?:\d+\?$)

enter image description here

RegEx

如果这不是您想要的表达式,则可以在regex101.com中修改/更改表达式,并添加或减少所需的边界。

RegEx电路

您还可以在jex.im中可视化您的表达式:

enter image description here

用于捕获组的JavaScript演示

const regex = /(?:^\w+\s)|(\d\?\(\w+\)\s)|(?:\d+\?$)/gm;
const str = `3A 4?(1) 5?(2) 6?(a) 7?(4) 8?(a) 9?(ii) 10?`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

答案 1 :(得分:0)

此模式([\(][\w]{1,3}[\)])\s[\d]{1,3}[\?]与开头的4?不匹配

您可以通过删除不需要的方括号来简化表达式,并添加一个可选部分以匹配1-3位数字,然后在前面加上问号:

(?:\d{1,3}\?)?(\(\w{1,3}\))\s\d{1,3}\?

Regex demo

如果您不希望单独匹配,而只需要1个单个匹配,并且数字问号部分也可能出现在括号之间而没有以下部分的情况下,则可以使用带有可选部分的重复组作为括号:

\d+\?(?:\(\w{1,3}\))?(?: \d+\?(?:\(\w{1,3}\))?)+

说明

  • \d+\?匹配1个以上的数字和?
  • (?:\(\w{1,3}\))?可选组以匹配括号部分
  • (?:非捕获组
    • \d+\?(?:\(\w{1,3}\))?匹配1个以上的数字和?,后跟括号的可选部分
  • )+关闭非捕获组并重复1次以上

Regex demo

注意

在示例的第一个模式中,缺少左括号

(([\(][\w]{1,3}
      ^ 

在第二个表达式中,在模式的结尾处有一个大括号)

答案 2 :(得分:0)

尝试以下模式:\d+\?(?:\([\da-z]+\))?

说明:

\d+-匹配一个或多个数字

\?-从字面上匹配?

(?:...)-非捕获组

\(-从字面上匹配(

[\da-z]+-匹配数字或小写字母中的一个或多个

\)-从字面上匹配)

?-最多匹配前一个模式,即\([\da-z]+\)

Demo

代码中的用法:

Sub Main()
    Dim matches = Regex.Matches("3A 4?(1) 5?(2) 6?(a) 7?(4) 8?(a) 9?(ii) 10?", "\d+\?(?:\([\da-z]+\))?")
    For Each match As Match In matches
        Console.WriteLine(match.Value)
    Next
    Console.ReadKey()
End Sub

更新

尝试更新模式:^(?:\d+(?:\?(?:\([\da-z]+\))?|[A-Z]+) ?)+$

Demo