Regex: сопоставлять шаблоны кроме как с предшествующими - PullRequest
3 голосов
/ 29 января 2020

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

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

Я хотел бы сопоставить все X.X.X.X, в которых нет слова paragraph перед ним, ie it должен соответствовать только 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 X с. Они варьируются от X.X до X.X.X.X.X

Ответы [ 3 ]

4 голосов
/ 29 января 2020

Ваш шаблон соответствует, потому что «абзац» не совпадает с «абзац [пробел]». Ваш шаблон не имеет пробела. Ваш текст делает.

Вы можете добавить пробел (возможно, условно?) К вашему взгляду. Поскольку вы хотите соответствовать различному числу X.X.X.X (вы сказали, что от X.X до X.X.X.X.X), нам необходимо включить X. также и в просмотр:

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

Live Example :

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. ноль или более раз не непосредственно перед матчем; и
  • , что X. повторяется от одного до четырех раз ({1,4}); и
  • То, что X следует сразу за этими тремя

X в моем примере A-Z0-9, и я сделал выражение без учета регистра, но вы можете настроить как Нужен.


Обратите внимание, что lookbehind был добавлен только в JavaScript недавно, в ES2018, поэтому для поддержки требуется современная JavaScript среда. Если вам нужно смотреть назад в более старых средах, вы можете проверить превосходную библиотеку XRegex Стивена Левитана .

Также обратите внимание, что внешний вид переменной длины, как указано выше, поддерживается не во всех языках (но поддерживается в JavaScript ... в современных двигателях).

0 голосов
/ 29 января 2020

Вы можете построить Regex итеративно -

  1. Игнорировать любое слово с предшествующим словом 'абзац' и пробелом.
  2. Поскольку ваш шаблон фиксированный, который состоит из из четырех чисел, разделенных точкой, можно предположить, что минимальное число цифр в этом четверке будет равно 1.
  3. Захват четверки чисел в группе захвата, которая будет использоваться позже.

Проверка регулярных выражений здесь .

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);
}
0 голосов
/ 29 января 2020

Если вы всегда хотите соответствовать группе из 4 предметов, вы можете сделать это следующим образом:

(?<!paragraph )([0-9]+.?){4}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...