Необходимо получить соответствие между указанными разделителями - PullRequest
2 голосов
/ 05 июля 2019

Я пытаюсь сопоставить определенное tags между разделителями двойных кавычек в предложении:

Look for `foo="x"` ONLY between the specific double block quote delimiters  [[foo="x"|bar="y"|baz="z"]]

Использование следующего регулярного выражения также соответствует foo="x" вне разделителей:

(?:(foo|bar|baz)="([^"]+)")+

Я попытался добавить положительный вид сзади: (?<=\[\[), но он возвращает мне только первые foo="x" в кавычках, но игнорирует совпадения bar="y" и baz="z".

const regex = /(?:(foo|bar|baz)="([^"]+)")+/gm;
const str = `Look for \`foo="x"\` ONLY between the specific double block quote delimiters  [[foo="x"|bar="y"|baz="z"]]`;
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}`);
    });
}

Ответы [ 2 ]

2 голосов
/ 05 июля 2019

Попробуйте немного другое определение ваших требований:

  • match name = "value" , с группами захвата для name и value ,
  • перед именем должно быть:
    • либо двойной открывающий кронштейн ([[),
    • или вертикальная черта (|),
  • после значения (и закрывающей двойной кавычки) должно быть:
    • либо двойная закрывающая скобка (]]),
    • или вертикальная черта (|).

Тогда регулярное выражение может быть следующим:

(?:\[\[|\|)(foo|ba[rz])="(\w+)"(?=]]|\|)

подробности:

  • (?:\[\[|\|) - содержимое до (будет частью матча, но не является частью какой-либо группы захвата),
  • (foo|ba[rz])="(\w+)" - имя / значение пара (с двойными кавычками),
  • (?=]]|\|) - содержание после (на этот раз выражается в виде положительный взгляд ).

Рабочий пример см. https://regex101.com/r/dj51GS/1

2 голосов
/ 05 июля 2019

Если ваши строки внутри [[ и ]] не имеют [ и ] простого

/(foo|bar|baz)="([^"]+)"(?=[^\][]*]])/g

будет работать для вас. Часть (?=[^\][]*]]) обеспечит наличие 0 или более символов, отличных от [ и ], а затем ] будут сразу справа от текущего местоположения. См. regex demo .

Самое безопасное решение состоит из двух шагов: 1) получить значение группы 1 с помощью /\[\[((foo|bar|baz)="([^"]+)"(?:\|(foo|bar|baz)="([^"]+)")*)]]/ (или более простого, но менее точного, но более универсального /\[\[\w+="[^"]+"(?:\|\w+="[^"]+")*]]/g, см. demo ) и 2) используйте /(foo|bar|baz)="([^"]+)"/g (или /(\w+)="([^"]+)"/g), чтобы извлечь необходимые значения из группы 1.

const x = '(foo|bar|baz)="([^"]+)"';                         // A key-value pattern block
const regex = new RegExp(`\\[\\[(${x}(?:\\|${x})*)]]`, 'g'); // Extracting the whole `[[]]`
const str = `Look for \`foo="x"\` ONLY between the specific double block quote delimiters  [[foo="x"|bar="y"|baz="z"]]`;
let m;
while (m = regex.exec(str)) {
    let results = [...m[1].matchAll(/(foo|bar|baz)="([^"]+)"/g)]; // Grabbing individual matches 
    console.log(Array.from(results, m => [m[1],m[2]]));
}

Шаблон \[\[((foo|bar|baz)="([^"]+)"(?:\|(foo|bar|baz)="([^"]+)")*)]] будет соответствовать

  • \[\[ - [[
  • ((foo|bar|baz)="([^"]+)"(?:\|(foo|bar|baz)="([^"]+)")*) - Группа 1:
    • (foo|bar|baz) - foo, bar или baz
    • = - =
    • "([^"]+)" - ", 1 или более символов, отличных от " и "
    • (?:\|(foo|bar|baz)="([^"]+)")* - 0 или более повторений | и шаблон, описанный выше
  • ]] - ]] подстрока.

См. Демоверсию regex .

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