Найти совпадающие матчи

Учитывая строку (строку из текстового файла), я хотел бы найти все подстроки, построенные следующим образом:

[[слова]]

Например:

[[foo [[bar]]

должны возвращать оба

[[foo [[bar]]

а также

[[ бар ]]

Другой пример:

[[foo]] и [[bar]]

Должна производить

[[Foo]]

а также

[[бар]]

Я думал о форуме

\[\[.+\]\] 

Но он работает неправильно (он слишком много соответствует).

Спасибо за помощь!

2 Solutions collect form web for “Найти совпадающие матчи”

Перекрывающиеся совпадения: используйте Lookahead

Для ленивого совпадения используйте это регулярное выражение:

 (?=(\[\[.?*\]\])) 

В Python:

 import re pattern = r"(?=(\[\[.*?\]\]))" print(re.findall(pattern, "[[foo [[ bar ]]")) print(re.findall(pattern, "[[foo]] and [[bar]]")) 

Вывод:

 ['[[foo [[ bar ]]', '[[ bar ]]'] ['[[foo]]', '[[bar]]'] 

Для «жадного перекрытия» используйте (?=(\[\[.*\]\]))

Вывод:

 ['[[foo [[ bar ]]', '[[ bar ]]'] ['[[foo]] and [[bar]]', '[[bar]]'] 

объяснение

  • Lookahead (?= ... ) утверждает, что то, что находится внутри круглых скобок, может быть сопоставлено (но не соответствует ему, так что мы можем найти совпадающие совпадения)
  • Скобки вокруг `([[. *]]) Фиксируют согласованную строку для группы 1
  • \[\[ соответствует [[
  • .* gredily соответствует любым символам
  • Квантор звезды в .*? делается «ленивым» ? так что точка соответствует только нескольким символам, необходимым для того, чтобы разрешить следующий токен (кратчайшее совпадение). Без ? , .* сначала соответствует всей строке, а затем возвращается только по мере необходимости, чтобы следующий токен соответствовал (самое длинное совпадение).
  • \]\] соответствует ]]

Справка

  • Условные обозначения Lookahead и Lookbehind Zero-Length
  • Освоение Lookahead и Lookbehind
  • Множество степеней жадности Regex
  • Повторение со звездой и плюсом

Это использует утверждение Positive Lookahead для захвата, возвращая совпадающие совпадения:

 >>> re.findall(r'(?=(\[\[.*?\]\]))', '[[foo [[ bar ]]') # ['[[foo [[ bar ]]', '[[ bar ]]'] >>> re.findall(r'(?=(\[\[.*?\]\]))', '[[foo]] and [[bar]]') # ['[[foo]]', '[[bar]]'] 

Обратите внимание на ? после квантификатора * делающего ваш матч не жадным.

  • Matlab-эквивалент `endsWith`: как фильтровать список имен файлов относительно их расширения?
  • Как сопоставить смайлик в предложении с регулярными выражениями
  • Как указать диапазон символов Unicode
  • Модуль «regex» Python: значение размытости
  • Исходная строка и регулярное выражение в Python
  • Python: извлечение предложения с определенным словом
  • Как я могу гарантировать, что re.findall () останавливается в нужном месте?
  • Как заменить N-й вид иглы в стоге сена? (Python)
  • Python - лучший язык программирования в мире.