Как делает регулярное выражение‘ (? <= #) [^#] + (? =#)’ работа?

Я имею следующий regex в программе C# и испытываю затруднения при понимании этого:

(?<=#)[^#]+(?=#)

Я сломаю его к тому, что я думаю, что понял:

(?<=#)    a group, matching a hash. what's `?<=`?
[^#]+     one or more non-hashes (used to achieve non-greediness)
(?=#)     another group, matching a hash. what's the `?=`?

Таким образом, проблема, которую я имею, ?<= и ?< часть. От чтения MSDN, ?<name> используется для именования групп, но в этом случае угловая скобка никогда не закрывается.

Я не мог найти ?= в документах и поиске это действительно трудно, потому что поисковые системы главным образом проигнорируют те специальные символы.

20
задан Donal Fellows 23 June 2010 в 09:42
поделиться

3 ответа

Они называются поисковыми запросами; они позволяют вам утверждать, совпадает ли шаблон или нет, без фактического совпадения. Существует 4 основных метода поиска:

  • Положительный поиск: посмотрите, МОЖЕМ ли мы сопоставить шаблон ...
    • (? = Шаблон) - ... вправо от текущей позиции (смотрите вперед )
    • (? <= Шаблон) - ... слева от текущей позиции (посмотрите за )
  • Отрицательные поисковые пути - посмотрите, можем ли мы НЕ сопоставить шаблон
    • (?! шаблон) - ... вправо
    • (? - ... влево

В качестве простого напоминания для поиска:

  • = является положительным , ! отрицательный
  • < выглядит позади , в противном случае он выглядит впереди

Ссылки


Но зачем использовать поисковые запросы?

Кто-то может возразить, что поисковые запросы в приведенном выше шаблоне не нужны, и # ([^ #] +) # отлично справится с этой задачей (извлечение строки, захваченной \ 1 , чтобы получить не- # ).

Не совсем. Разница в том, что, поскольку поиск не соответствует # , его можно «использовать» снова при следующей попытке найти совпадение.Упрощенно говоря, поисковые запросы позволяют «совпадениям» перекрываться.

Рассмотрим следующую входную строку:

and #one# and #two# and #three#four#

Теперь # ([az] +) # даст следующие совпадения (, как показано на rubular.com ):

and #one# and #two# and #three#four#
    \___/     \___/     \_____/

Сравните это с (? <= #) [Az] + (? = #) , которое соответствует:

and #one# and #two# and #three#four#
     \_/       \_/       \___/ \__/

К сожалению, это нельзя продемонстрировать на rubular.com, поскольку он не поддерживает смотреть за. Однако он поддерживает предварительный просмотр, поэтому мы можем сделать что-то подобное с # ([az] +) (? = #) , которое соответствует (, как показано на rubular.com ):

and #one# and #two# and #three#four#
    \__/      \__/      \____/\___/

Ссылки

33
ответ дан 30 November 2019 в 00:00
поделиться

Как упомянул другой постер, это lookarounds, специальные конструкции для изменения того, что и когда сопоставляется. Здесь сказано:

(?<=#)    match but don't capture, the string `#`
            when followed by the next expression

[^#]+     one or more characters that are not `#`, and

(?=#)     match but don't capture, the string `#`
            when preceded by the last expression

Таким образом, это будет соответствовать всем символам между двумя #s.

Lookaheads и lookbehinds очень полезны во многих случаях. Рассмотрим, например, правило "Искать все bs, за которыми не следует a". Вашей первой попыткой может быть что-то вроде b[^a], но это неправильно: это также будет соответствовать bu в bus или bo в boy, но вам нужен только b. И он не будет соответствовать b в cab, даже если за ним не следует a, потому что больше нет символов для поиска.

Чтобы сделать это правильно, вам нужен предпросмотр: b(?!a). Это означает "сопоставьте b, но не сопоставляйте a после этого, и не делайте это частью сопоставления". Таким образом, он будет соответствовать только b в bolo, что вам и нужно; аналогично он будет соответствовать b в cab.

4
ответ дан 30 November 2019 в 00:00
поделиться

Они называются осмотрами : http://www.regular-expressions.info/lookaround.html

1
ответ дан 30 November 2019 в 00:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: