RegEx для прохождения пунктуации - PullRequest
2 голосов
/ 29 мая 2019

Я использую:

(.*) CO\s?[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"](.*) 

для представления

3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY). 

Однако первая одинарная кавычка не может быть покрыта кодом регулярного выражения.Не могли бы вы сказать мне, почему?

s/(.*) CO\s?[\(.*\)|\[.*\]|\{.*\}|''.*''|".*"](.*)/$1 CO $2

Я ожидаю получить:

3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY)

но я получу

3M CO A'(MINNESOTA MINING AND MANUFACTURING COMPANY)

Ответы [ 3 ]

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

Ваше регулярное выражение должно быть выражено до

/(.*)\sCO\s?(\(.+\).*|".+".*|'.+'.*|{.+}.*|\[.+\].*)/

(.*) Первая группа захвата захватит начальную группу («3M» в вашем примере)

\sCO\s Затем ищет пробел, за которым следует CO, за которым следует пробел

(".+".* etc.) Вторая группа захвата, которая ищет начальную кавычку или скобку, за которой следует хотя бы один символ чего-либо, за которым следует закрывающая кавычка, а затем любое число любого символа

Почему оригинальное регулярное выражение не сработало

В исходном регулярном выражении [\(.*\)|\[.*\]|\{.*\}|''.*''|".*"] можно упростить до [''.*''] (для предоставленной вами строки). Я понимаю, что для других строк вы можете искать (.*) или [.*] или {.*} или ".*", но для строки "3M" важна только [''.*''], поэтому мы просто посмотрим на это.

Таким образом, [''.*''] просто означает: сопоставить любой символ в списке внутри [] в любом порядке. В этом случае в списке три уникальных символа: ', . и * (хотя вы повторили ' 3 раза). Так что это соответствует первому '. Но поскольку это совпадение находится за пределами вашей группы захвата (), то это первое ' не включается в ответ вашей группы захвата.

Таким образом, следующее совпадение с (.*) соответствует всему остальному, что идет после первого ', и включает их во вторую группу сопоставления, то есть A'(MINNESOTA MINING AND MANUFACTURING COMPANY) без ' впереди.

Имеет ли это смысл?

Демо

Если вы хотите убедиться, что формат включает 'A' или [A] или "A" или {A} или (A), то это то, что вы хотите:

let regex = /(.*)\sCO\s?(\(.+\)|".+".*|'.+'.*|{.+}.*|\[.+\].*)/;

[pattern, match1, match2] = "3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY)".match(regex);
console.log(match1 + " CO " + match2);
//3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY)

[pattern, match1, match2] = '3M CO (A)(MINNESOTA MINING AND MANUFACTURING COMPANY)'.match(regex);
console.log(match1 + " CO " + match2);
//3M CO (A)(MINNESOTA MINING AND MANUFACTURING COMPANY)

[pattern, match1, match2] = '3M CO "A"(MINNESOTA MINING AND MANUFACTURING COMPANY)'.match(regex);
console.log(match1 + " CO " + match2);
//3M CO "A"(MINNESOTA MINING AND MANUFACTURING COMPANY)

[pattern, match1, match2] = "3M CO [A](MINNESOTA MINING AND MANUFACTURING COMPANY)".match(regex);
console.log(match1 + " CO " + match2);
//3M CO [A](MINNESOTA MINING AND MANUFACTURING COMPANY)

[pattern, match1, match2] = "3M CO {A}(MINNESOTA MINING AND MANUFACTURING COMPANY)".match(regex);
console.log(match1 + " CO " + match2);
//3M CO {A}(MINNESOTA MINING AND MANUFACTURING COMPANY)
0 голосов
/ 29 мая 2019

' не совпадает, потому что во второй группе захвата вы используете класс символов, который может быть записан как CO\s?[(.*)|[\]{}'"], а затем он будет соответствовать CO '

Таким образом, ваш шаблон на самом деле выглядит:

(.*) CO\s?[.*()|[\]{}'"](.*)
^         ^             ^
group 1   Char class    group 2

Что вы можете сделать, чтобы получить соответствие в 2 группах, это использовать:

(.*?)CO\s?((?:(['"]).*?\3|\(.*?\)|\[.*?\]|\{.*?\}).*)

Пояснение

  • (.*?) Группа захвата 1, соответствует любому символу, кроме новой строки, не жадный
  • CO\s? Соответствие CO и дополнительный символ пробела
  • ( Группа захвата 2
    • (?:Группа без захвата, сопоставьте любой из параметров
      • (['"]).*?\3 Match 'или "и используйте обратную ссылку на то, что захватывается
      • | или
      • \(.*?\) Match( .... )
      • | Или
      • \[.*?\] Совпадение [ .... ]
      • | Или
      • \{.*?\} Match { .... }
    • ) Закрыть группу без захвата
    • .* Соответствовать любомусимвол до конца строки
  • ) Закрыть группу 2

Демонстрация регулярных выражений

Обратите внимание, что .*? не является жадным, чтобы избежать ненужного возврата и перебора соответствия.

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

Я предполагаю, что здесь мы хотим разработать выражение и сопоставить наши входные данные, часть за частью, например:

(.+?)\s+CO\s+(['"].+?['"])([(\[{]).+?([)\]}])

Мы добавили дополнительные границы, которые можно уменьшить, если не желательно.

У нас есть три основные группы захвата:

(.+?) # anything before Co;
(['"].+?['"]) # the quotation part; and
([(\[{]).+?([)\]}]) # inside various brackets included those, which we can escape, if required.

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

DEMO

Демо

Этот фрагмент показывает, как работают группы захвата:

const regex = /(.+?)\s+CO\s+(['"].+?['"])([(\[{]).+?([)\]}])/mg;
const str = `3M CO 'A'(MINNESOTA MINING AND MANUFACTURING COMPANY)
3M CO 'A'[MINNESOTA MINING AND MANUFACTURING COMPANY]
3M CO 'A'{MINNESOTA MINING AND MANUFACTURING COMPANY}
3M CO "A"{MINNESOTA MINING AND MANUFACTURING COMPANY}`;
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}`);
    });
}

RegEx

Если это выражение нежелательно, его можно изменить / изменить в regex101.com .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...