Regex: шаблон соответствия, если он не в начале

Предположим, что следующие строки:

aaa bbb ccc
bbb aaa ccc

Я хочу сопоставить aaa, если он не находится в начале строки. Я пытаюсь скрыть это, сделав что-то вроде этого:

[^^]aaa

Но я не думаю, что это правильно. Используя preg_replace.

Ответ 1

Вы можете использовать внешний вид, чтобы убедиться, что это не в начале. (?<!^)aaa

Ответ 2

Поскольку я пришел сюда через поиск Google и был заинтересован в решении, которое не использует lookbehind, вот мои 2 цента.

Шаблон [^^]aaa соответствует символу, отличному от ^, а затем 3 a в любом месте внутри строки. [^...] является отрицательным символьным классом, где ^ не считается специальным символом. Обратите внимание на первый ^, который сразу после [ является особенным, поскольку он обозначает отрицание, а второй - буква буквального символа.

Таким образом, a ^ не может быть внутри [...] для обозначения начала строки.

Решение состоит в использовании любого негативного обратного обзора, эти два будут работать одинаково хорошо:

(?<!^)aaa

и просмотр:

(?!^)aaa

Почему тоже работает lookahead? Lookarounds - это утверждения с нулевой шириной, а якоря тоже имеют нулевую ширину - они не потребляют текст. Буквально, (?<!^) проверяет, нет ли начала позиции строки сразу слева от текущего местоположения, а (?!^) проверяет, нет ли начала позиции строки сразу справа от текущего местоположения. Те же места проверяются, поэтому обе работают хорошо.

Ответ 3

Если вы не хотите использовать lookbehind, используйте это регулярное выражение:

/.(aaa)/

И используйте matched group # 1.

Ответ 4

Эта ситуация - первый раз, когда я вижу, как превзошли ожидания \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).

Ответ 5

Это поможет найти то, что вы ищете:

(?<!^)aaa

Пример использования: http://regexr.com?34ab2

Ответ 6

Я пришел сюда, чтобы найти решение для движка re2, используемого в электронных таблицах Google, который не поддерживает обходные пути. Но ответы здесь дали мне идею использовать следующее. Я не понимаю, почему я должен заменить захваченную группу, но в любом случае, это работает.

ааа bbb ccc
BBB AAA CCC

([^^])aaa

заменить на:

$1zzz

переходит в:

zzz bbb ccc
BBB AAA CCC