Orion9

|
Posted: Sun Jul 19, 2026 11:59 Post subject: |
|
|
| yozhik wrote: | | Поэтому к Бате вопрос: |
Согласен, нужно уточнить задачу. Но раз уж Batya озаглавил тему так, что можно делиться собственным неудачным (или удачным?) опытом, то помню, когда сталкнулся в справке с такими примерами:
| Code: | RegEx Находит
foob.*r foobar, foobalkjdflkj9r и foobr
foob.+r foobar, foobalkjdflkj9r, но не foobr
foob.?r foobar, foobbr и foobr, но не foobalkj9r
fooba{2}r foobaar
fooba{2}r ` foobaar, foobaaar, foobaaaar` и т. д.
fooba{2,3}r foobaar, или foobaaar, но не foobaaaar
(foobar){8,10} 8, 9 или 10 экземпляров foobar (() это Группа) |
Очень мне не понравился этот fooba{2}r `. Хотелось бы услышать пояснений, но не догадался тогда у болвана спросить
 почему находит foobaar, foobaaar, foobaaaar` Если ваше регулярное выражение fooba{2}r находит слова с тремя, четырьмя или более буквами «а» (foobaaar, foobaaaar), это происходит по одной из двух причин:
## 1. Отсутствие строгих границ слова (Самая частая причина)
Движок регулярных выражений ищет частичное совпадение внутри строки. Квантификатор {2} требует, чтобы букв «а» было минимум две.
Когда движок видит слово foobaaar:
* Он проверяет префикс foob.
* Затем он видит группу aa (первые две буквы «а») — это условие a{2} выполнено.
* Но третья буква «а» для него становится частью следующего символа. Однако в вашем шаблоне дальше идёт буква r, а не a. Движок спотыкается.
* Тогда он включает механизм бэктрекинга (отката): он сдвигает своё окно поиска на одну букву вправо. Он берёт вторую и третью буквы «а» как выполнение условия a{2}, а за ними как раз идёт нужная буква r .
* В итоге внутри слова foob[aaa]r он успешно выделяет подстроку foob[aar] .
## 2. Специфика старого движка AkelPad
Если вы тестируете это в AkelPad, то его встроенный (старый стандартный) движок регулярных выражений имеет упрощенный синтаксис. В некоторых его версиях квантификатор {n} работает не как «строго n раз», а как «n или более раз» (то есть аналогично {n,}).
------------------------------
## 🛠️ Как это исправить?
Чтобы заставить движок искать строго две буквы «а» и игнорировать слова, где их больше, используйте один из вариантов:
1. Добавить негативную проверку (Lookbehind/Lookahead):
Это запретит буквам «а» стоять до или после нашей пары.
fo(?<!a)ba{2}(?!a)r `
2. Для AkelPad (через явное указание не-буквы):
Если вы ищете слова целиком, ограничьте их метасимволом границы слова \b:
\bfooba{2}r\b `
Но учтите, если в движке AkelPad баг с квантификатором, то для строго двух «а» надежнее написать их вручную без фигурных скобок: \bfoobaar\b |
|