Предположим, что следующие строки:
aaa bbb ccc
bbb aaa ccc
Я хочу сопоставить aaa
, если он не находится в начале строки. Я пытаюсь скрыть это, сделав что-то вроде этого:
[^^]aaa
Но я не думаю, что это правильно. Используя preg_replace
.
Предположим, что следующие строки:
aaa bbb ccc
bbb aaa ccc
Я хочу сопоставить aaa
, если он не находится в начале строки. Я пытаюсь скрыть это, сделав что-то вроде этого:
[^^]aaa
Но я не думаю, что это правильно. Используя preg_replace
.
Вы можете использовать внешний вид, чтобы убедиться, что это не в начале. (?<!^)aaa
Поскольку я пришел сюда через поиск Google и был заинтересован в решении, которое не использует lookbehind, вот мои 2 цента.
Шаблон [^^]aaa
соответствует символу, отличному от ^
, а затем 3 a
в любом месте внутри строки. [^...]
является отрицательным символьным классом, где ^
не считается специальным символом. Обратите внимание на первый ^
, который сразу после [
является особенным, поскольку он обозначает отрицание, а второй - буква буквального символа.
Таким образом, a ^
не может быть внутри [...]
для обозначения начала строки.
Решение состоит в использовании любого негативного обратного обзора, эти два будут работать одинаково хорошо:
(?<!^)aaa
и просмотр:
(?!^)aaa
Почему тоже работает lookahead? Lookarounds - это утверждения с нулевой шириной, а якоря тоже имеют нулевую ширину - они не потребляют текст. Буквально, (?<!^)
проверяет, нет ли начала позиции строки сразу слева от текущего местоположения, а (?!^)
проверяет, нет ли начала позиции строки сразу справа от текущего местоположения. Те же места проверяются, поэтому обе работают хорошо.
Если вы не хотите использовать lookbehind, используйте это регулярное выражение:
/.(aaa)/
И используйте matched group # 1
.
Эта ситуация - первый раз, когда я вижу, как превзошли ожидания \K
Интересно.
Обычно захват групп и поиск обходят дополнительные шаги. Но из-за характера этой задачи механизм регулярных выражений может быстрее перемещаться по строке в поисках aaa
затем искать начало привязки строки.
Я добавлю пару шаблонов \K
для сравнения.
Я использую s
модификатор шаблона в случае ведущий персонаж может быть символ новой строки (который .
Обычно не совпадают). Я просто подумал, что добавлю это соображение, чтобы превентивно рассмотреть крайнее дело, которое я могу поставить.
Опять же, это интересный сценарий, потому что во всех других случаях регулярных выражений, с которыми я имел дело, \K
превосходит другие методы.
Таблица сравнения количества шагов:
| '~.\Kaaa~s' | '~.+?\Kaaa~s' | '(?<!^)aaa' | '(?!^)aaa' | '.(aaa)' |
--------------|-------------|---------------|-------------|------------|----------|
'aaa bbb ccc' | 12 steps | 67 steps | 8 steps | 8 steps | 16 steps |
--------------|-------------|---------------|-------------|------------|----------|
'bbb aaa ccc' | 15 steps | 12 steps | 6 steps | 6 steps | 12 steps |
Вывод: чтобы узнать об эффективности ваших шаблонов, сплит их на regex101.com и сравните количество шагов.
Кроме того, если вы точно знаете, какую подстроку вы ищете, и вам не нужен шаблон регулярных выражений, тогда вы должны использовать strpos()
в качестве передового опыта (и просто проверить, что возвращаемое значение > 0
).
Это поможет найти то, что вы ищете:
(?<!^)aaa
Пример использования: http://regexr.com?34ab2
Я пришел сюда, чтобы найти решение для движка re2, используемого в электронных таблицах Google, который не поддерживает обходные пути. Но ответы здесь дали мне идею использовать следующее. Я не понимаю, почему я должен заменить захваченную группу, но в любом случае, это работает.
ааа bbb ccc
BBB AAA CCC
([^^])aaa
заменить на:
$1zzz
переходит в:
zzz bbb ccc
BBB AAA CCC