регулярное выражение исключает совпадения, которые не соответствуют одному из двух шаблонов, разделенных разделителем - PullRequest
0 голосов
/ 06 января 2020

В Javascript с использованием string.match():

У меня есть строка вроде: foo_2:asc,foo2:desc,foo3,foo4:wrong

совпадения должны выглядеть как ["foo_2:asc", "foo2:desc", "foo3"]

, но вместо лучшее, что я могу получить до сих пор, это совпадение, возвращающее ["foo_2:asc", "foo2:desc", "foo3", "wrong"]

регулярное выражение, которое я использую в настоящее время для указанного выше неправильного соответствия: /([a-z0-9_]+?[:asc|:desc]*?)(?=,|$)/gi

Мне также нужно регулярное выражение который возвратит противоположное, то есть найдет совпадение для всех шаблонов между разделителем, который не соответствует правилам шаблонов thing_1:asc, thing_1:desc или thing_1, т.е. это будет использоваться для проверки строки, в то время как другой будет использоваться для сбора значений (то есть вместо разделения строки вручную). Таким образом, результатом оригинала будет ["foo4:wrong"] как часть этой строки, которая не соответствует шаблону.

Ответы [ 3 ]

1 голос
/ 06 января 2020

Предполагая, что единственными допустимыми формами являются слова, за которыми следует одно из :asc, :desc или ничего, вы можете сделать то, что вы хотите, разбив строку сначала на ,, а затем на : и проверив, есть два значения в результате последнего разделения, а второе не является одним из asc или desc:

const str = 'foo_2:asc,foo2:desc,foo3,foo4:wrong';
const errs = str.split(',').filter(v => v.split(':').length == 2 && ['asc', 'desc'].indexOf(v.split(':')[1]) == -1);
console.log(errs);

Если вы должны использовать регулярное выражение, вы можете разделить на ,, а затем отфильтровать на основе значения, не соответствующего ^\w+(:(asc|desc))$:

const str = 'foo_2:asc,foo2:desc,foo3,foo4:wrong';
const errs = str.split(',').filter(v => !v.match(/^\w+(:(?:asc|desc))?$/));
console.log(errs);

Если формат строки гарантированно равен \w+(:\w+)?(,\w+(:\w+)?)*, вы можете упростить это до:

const str = 'foo_2:asc,foo2:desc,foo3,foo4:wrong';

const errs = str.match(/\w+:(?!(?:asc|desc)\b)\w+/g);
console.log(errs);
0 голосов
/ 06 января 2020

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

/(^|\,)([a-z0-9_]+?(:asc|:desc)*?)(?=,|$)/gi

также обратите внимание [: asc |: desc] изменено на (: asc |: des c), чтобы избежать ложных положительных случаев, таких как:

foo5:aaa,foo6:d,foo7:,foo8|,et:c

это просто совпадения с любым символом в квадратных скобках.

Что касается обратного, попробуйте что-то вроде:

/(^|\,)(?!([a-z0-9_]+?(:asc|:desc)*?)(?=,|$))[^,$]+/gi

, кажется, делает эту работу.

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

Для матча я придумал

/(?<=(^|,))((\w+(?!:)|\w+(:asc|:desc)))(?=($|,))/g

Пример: https://regex101.com/r/QLJeDV/3/

> "foo_2:asc,foo2:desc,foo3,foo4:wrong".match(/(?<=(^|,))((\w+(?!:)|\w+(:asc|:desc)))(?=($|,))/g)
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]

Или даже

/(?<=(^|,))\w+(:asc|:desc)?(?=($|,))/g

должно сработать. Пример: https://regex101.com/r/QLJeDV/6/

> "foo_2:asc,foo2:desc,foo3,foo4:wrong".match(/(?<=(^|,))\w+(:asc|:desc)?(?=($|,))/g)
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]

Они используют lookahead и lookbehind.

Для «противоположного» я ​​не знаю, как сопоставить что-то, а затем «отрицать» более поздний шаблон, но знаю только, как отрицать результат того, является ли он полным совпадением, поэтому мне пришлось его разбить. «Противоположность»:

> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => !/^((\w+(?!:)|\w+(:asc|:desc)))$/.test(s))
[ 'foo4:wrong' ]

и «оригинал»:

> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => /^((\w+(?!:)|\w+(:asc|:desc)))$/.test(s))
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]

Или это можно упростить как:

> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => !/^\w+(:asc|:desc)?$/.test(s))
[ 'foo4:wrong' ]

> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => /^\w+(:asc|:desc)?$/.test(s))
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...