Ответ 1
Попробуйте следующее:
(\b(?<!['"])[a-zA-Z_][a-zA-Z_0-9]*\b(?!['"]))
Против этой строки:
john "michael" michael 'michael elt0n_john 'elt0n_j0hn' 1 2 3 4 5 6
Он будет соответствовать nr 1 john
, nr 3 Michael
и nr 5 elt0n_john
У меня есть некоторое регулярное выражение, которое я просматриваю на всей HTML-странице, ищущей строки и заменяя их, однако, если строка находится в одинарных или двойных кавычках, я не хочу, чтобы она соответствовала.
Текущее Regex: ([a-zA-Z_][a-zA-Z0-9_]*)
Я хотел бы совместить steve
, john
, cathie
и john likes to walk
(x3)
но не "steve"
, 'sophie'
или "john"'likes'"cake"
Я пробовал (^")([a-zA-Z_][a-zA-Z0-9_]*)(^")
, но не получал совпадений?
Тестовые случаи:
(steve=="john") would return steve
("test"=="test") would not return anything
(boob==lol==cake) would return all three
Попробуйте следующее:
(\b(?<!['"])[a-zA-Z_][a-zA-Z_0-9]*\b(?!['"]))
Против этой строки:
john "michael" michael 'michael elt0n_john 'elt0n_j0hn' 1 2 3 4 5 6
Он будет соответствовать nr 1 john
, nr 3 Michael
и nr 5 elt0n_john
Вы можете попробовать:
preg_match_all('#(?<!["\']) \b \w+ \b (?!["\'])#x', $str, $matches);
\w+
соответствует символам слов, но позволяет, например, 0123sophie
. \b
соответствует границам слов и, таким образом, гарантирует, что утверждения против кавычек не заканчиваются слишком рано.
Однако это регулярное выражение также не сможет найти слова, которые имеют только одну цитату "до или после".
Для этого вам, вероятно, понадобится темная магия:
'~(?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\')(*SKIP)(*F)|([a-zA-Z_][a-zA-Z0-9_]*)~'
Часть (?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\')
соответствует строке в одиночных или двойных кавычках и реализует обратную косую черту. (*SKIP)(*F)
пропускает строку с кавычками и приводит к сбою. ([a-zA-Z_][a-zA-Z0-9_]*)
- это ваше регулярное выражение.
PS: Если вы используете это на скриптах PHP, вы можете вместо этого использовать Tokenizer. Таким образом, вы могли бы, например, исключить ключевые слова (например, class
или abstract
, я не знаю, нужно ли вам это), и вам будет намного лучше обрабатывать граничные случаи (например, HEREDOC).
Pez, воскрешая этот древний вопрос, потому что текущий ответ не совсем правильный (и я не уверен, что какое-либо решение может быть).
Он не будет соответствовать john
, когда он находится в неполных кавычках, например, в "john
, john"
, 'john
и john'
(ситуации, которые могут произойти с john birthday
и т.д. См. эта демонстрация.
Это альтернативное решение просто пропускает любой контент в кавычках:
(?:'[^'\n]*'|"[^"\n]*")(*SKIP)(*F)|\b[a-zA-Z_][a-zA-Z_0-9]*\b
Смотрите демо
В любом случае, с кавычками, никакое решение не идеально, потому что вы всегда рискуете иметь несбалансированные кавычки. В этом случае я попытался смягчить проблему, предположив, что если она на другой строке, это другая строка.
Ссылка
Хорошо, я думаю, что у меня есть это, и оно работает для ваших тестовых случаев:
(?<!"|'|\w)(\w+)(?!"|'|\w)
Выполнен с функцией регулярного выражения look-ahead/look-behind.