Квантификаторы регулярных выражений - столько, сколько между двумя символами

Я пытаюсь найти весь текст между двумя символами, но иногда строка содержит символ-разделитель.

Например, если я использую

(.*?)=(.*?),*

В следующей строке:

color=blue,weight=100kg,

Это приведет к:

match #1: color=blue
match #2: weight=100kg

Однако, если у меня есть следующая строка:

color=blue,red,weight=100kg,

Это приведет к:

match #1: color=blue
match #2: red,weight=100kg

Как я могу заставить регулярное выражение возвращать следующее? (обрезка строки в последнем вхождении символа запятой)

match #1: color=blue,red
match #2: weight=100kg

Обратите внимание, что количество цветов, разделенных запятой, может быть больше 3 или вообще отсутствовать.

Заранее спасибо,


person Haddock-san    schedule 02.08.2017    source источник
comment
вместо использования точки для описания ключа используйте класс символов, исключающий запятую (а также знак равенства).   -  person Casimir et Hippolyte    schedule 02.08.2017
comment
Для какого языка/среды должно подходить регулярное выражение? Как вы реализуете этот шаблон. Нам нужен языковой тег в вопросе. @Хаддок   -  person mickmackusa    schedule 01.06.2019
comment
@mickmackusa Ответ на вопрос был дан 2 года назад, но спасибо за интерес! Вы можете использовать регулярное выражение в нескольких средах и языках. Мой вопрос связан с синтаксисом Regex и не зависит от любого языка программирования.   -  person Haddock-san    schedule 01.08.2019
comment
Это довольно неудачная строка, которую вы пытаетесь разобрать. Когда значения могут содержать символ-разделитель, пора вернуться к структуре данных.   -  person mickmackusa    schedule 01.08.2019
comment
Является ли ваш образец текста всей строкой? или текст является подстрокой большей части текста? Можно ли сделать вызов функции разделения? Как может измениться ваш вклад? Всегда ли существует более двух подстрок? все меньше?   -  person mickmackusa    schedule 01.08.2019


Ответы (3)


Вы можете использовать это регулярное выражение:

[^,]+=[^=]+(?=,) где

[^,]+ - имя параметра

[^=]+(?=,) - будет захвачено значение параметра, которое может содержать все, кроме символа = и должно заканчиваться запятой.

пример regex101

person ikleschenkov    schedule 02.08.2017

Немного поигравшись с отрицательными классами символов, вы сможете сопоставить его с

[^=,]+=(?:[^=,]+|,(?![^,=]+=))+

Это соответствует

  • [^=,]+ все, что не запятая или =
  • = следующие =
  • (?:[^=,]+|,(?=[^,=]+,))+ все, что не является запятой или запятой, за которой непосредственно не следует = без запятой между ними - повторяется как можно чаще

См. https://regex101.com/r/p8Bz9o/1.

person Sebastian Proske    schedule 02.08.2017

Семантика: если мы имеем дело со всей входной строкой, то сопоставление — это не задача, а разделение.

Это делает узор еще проще. ~,(?=[^,]+=)~ Вам нужно сопоставить запятую (использовать ее), за которой следуют незапятые, а затем знак равенства. Упреждающий просмотр выполняет необходимую работу, и истинные разделительные запятые уничтожаются в процессе.

Regex101: https://regex101.com/r/hwQyhl/1

Реализация PHP: (Демо)

$input = 'color=blue,red,weight=100kg,another=one,two,three,four,okay=enough,';

var_export(preg_split('~,(?=[^,]+=)~', rtrim($input, ','), 0, PREG_SPLIT_NO_EMPTY));

Выход:

array (
  0 => 'color=blue,red',
  1 => 'weight=100kg',
  2 => 'another=one,two,three,four',
  3 => 'okay=enough',
)
person mickmackusa    schedule 01.08.2019