Как упростить шаблон регулярных выражений? - PullRequest
2 голосов
/ 19 мая 2019

Я пытаюсь упростить регулярное выражение.

Я пытался сделать повторение для того же выражения, но когда я попытался упростить его с помощью () *, оно не сработало так, как работаетне определить шаблон, который я хочу.

Это мое регулярное выражение:

(([\(]\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 ]

1 голос
/ 19 мая 2019

Может быть, здесь мы можем упростить это по-другому, если это будет возможно.Например, у нас могло бы быть три образца, которые мы можем захватить, используя три группы захвата: начальную, конечную и среднюю группы, возможно похожие на:

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

enter image description here

RegEx

Если это не было вашим желаемым выражением, вы можете изменить / изменить выражения в regex101.com , а также добавить или уменьшить желаемые границы.

RegEx Circuit

Вы также можете визуализировать свои выражения в 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}`);
    });
}
0 голосов
/ 19 мая 2019

Попробуйте этот шаблон: \d+\?(?:\([\da-z]+\))?

Пояснение:

\d+ - соответствует одной или нескольким цифрам

\? - соответствует ? буквально

(?:...) - группа без захвата

\( - совпадение ( буквально

[\da-z]+ - соответствует одной или нескольким из цифр или строчных букв

\) - соответствует ) буквально

? - совпадать не более одного раза с предыдущим шаблоном, равным \([\da-z]+\)

Демо

Использование в коде:

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

UPDATE

Попробуйте обновить шаблон: ^(?:\d+(?:\?(?:\([\da-z]+\))?|[A-Z]+) ?)+$

Демо

0 голосов
/ 19 мая 2019

Этот шаблон ([\(][\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демо

Примечание

В первом паттеВ вашем примере пропущена открывающая скобка

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

Во втором выражении есть закрывающая скобка ) в конце шаблона.

...