Регулярное выражение для соответствия символу, но не тогда, когда оно заключено в кавычки - PullRequest
11 голосов
/ 18 сентября 2009

Мне нужно сопоставлять двоеточие (':') в строке, но не тогда, когда оно заключено в кавычки - либо символ ", либо".

Таким образом, у следующего должно быть 2 совпадения

something:'firstValue':'secondValue'    
something:"firstValue":'secondValue'

но это должно иметь только 1 совпадение

something:'no:match'

Ответы [ 5 ]

4 голосов
/ 18 сентября 2009

Если реализация регулярного выражения поддерживает обратные утверждения, попробуйте следующее:

:(?:(?<=["']:)|(?=["']))

Это будет соответствовать любому двоеточию, которому предшествует двойная или одинарная кавычка. Так что это касается только конструкции, как вы упомянули. something:firstValue не будет соответствовать.

Было бы лучше, если бы вы создали небольшой парсер, который читает побитовые байты ввода и запоминает, когда открыта цитата.

3 голосов
/ 18 сентября 2009

Регулярные выражения не имеют состояния. Отслеживание того, находитесь ли вы внутри кавычек или нет, является информацией о состоянии. Поэтому невозможно правильно обработать это, используя только одно регулярное выражение. (Обратите внимание, что некоторые реализации «регулярных выражений» добавляют расширения, которые могут сделать это возможным; здесь я говорю исключительно об «истинных» регулярных выражениях.)

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

$string =~ s/['"][^'"]*['"]//g;
my $match_count = $string =~ /:/g;

Первый найдет каждую последовательность, состоящую из кавычек, за которой следует любое количество символов, не заключенных в кавычки, и завершенную второй кавычкой, и удалит все такие последовательности из строки. Это исключит любые двоеточия, которые находятся в кавычках. (something:"firstValue":'secondValue' становится something:: и something:'no:match' становится something:)

Второй выполняет простой подсчет оставшихся двоеточий, которые будут начинаться с кавычек.

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

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

1 голос
/ 18 сентября 2009

Упс ... упустил момент. Забудь об остальном. Это довольно сложно сделать, потому что регулярное выражение не очень хорошо для подсчета сбалансированных символов (но реализация .NET, например, имеет расширение, которое может это сделать, но это немного сложно).

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

[^'"]:[^'"]

Вы можете дополнительно обернуть кавычки в группы без захвата.

(?:[^'"]):(?:[^'"])

Или вы можете использовать утверждение.

(?<!['"]):(?!['"])
0 голосов
/ 14 августа 2018

Вы можете попытаться поймать строки с помощью кавычек

/(?<q>'|")([\w ]+)(\k<q>)/m

Первый шаблон определяет допустимые типы кавычек, второй шаблон принимает все Word-цифры и пробелы. Очень хорошо это решение, оно принимает ТОЛЬКО строки, в которых совпадают открывающие и закрывающие кавычки.

Попробуйте на regex101.com

0 голосов
/ 18 сентября 2009

Я придумал следующую слегка тревожную конструкцию:

(?<=^('[^']*')*("[^"]*")*[^'"]*):

Он использует утверждение заглядывания, чтобы убедиться, что вы сопоставляете четное число кавычек от начала строки до текущего двоеточия. Это позволяет встраивать одинарные кавычки в двойные кавычки и наоборот. Как в:

'a":b':c::"':" (совпадения в позициях 6, 8 и 9)

EDIT

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

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