захватить скороговорку с помощью letf и правого пролета, не включая этот шаблон - PullRequest
0 голосов
/ 07 февраля 2020

Мне не удается найти решение моей проблемы с регулярным выражением.

Вот текст: My text is so interesting, depending "interesting" meaning of course.

Я хочу сопоставить все строки, содержащие, например, interest.{3} и максимально растягивая влево и вправо, не сопоставляя interest.{3} снова. Поэтому я бы хотел, чтобы эти матчи были такими:

My text is so interesting, depending "interestin

nteresting, depending "interesting" meaning of course.

Есть ли способ достичь этого с помощью регулярного выражения PCRE?

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Помимо ответа @ Booboo, здесь есть регулярное выражение, которое работает для этого. Интересно, что это не работает в Java, но очень хорошо в Python. Одно из отличий состоит в том, что нет обратной ссылки, позволяющей считать interesting и interested. совпадениями в одном и том же тексте. Вы можете попробовать это на regex101.com . Он там работает.

(?=((^|interest.{3}).*?interest.{3}.*?(interest.{3}|$)))

Объяснение

  • Пусть X = interest.{3}. Затем это регулярное выражение сводится к более общему (?=((^|X).*?X.*?(X|$))).
  • Кроме того, я посчитал, что выражение «направо и налево от X» такое же, как «X в середине диапазона» ( с некоторыми оговорками, конечно).

Исходя из этого:

  1. Все регулярные выражения являются положительным взглядом с группами захвата (?=(regex)). Это означает, что хотя совпадение будет выполнено против X, оно не будет перемещать свою позицию в конец текущего совпадения (чтобы искать следующее совпадение). Вместо этого он будет постепенно перемещать символ за символом в строке, подбирая все совпадения из-за захвата групп. (Однако в Java кажется, что он работает по-другому.)
  2. Группа захвата (^|X) допускает совпадение для начала текста или X (граничный регистр).
  3. Второй X должен учитывать присутствие X в середине "промежутка".
  4. Группа захвата (X|$), как и первая в точке (2), имеет вид чтобы учесть границу X, которая также может быть EOT.
0 голосов
/ 07 февраля 2020
import re

text = 'Here is text : My text is so interesting, depending "interesting" meaning of course.'

s = text
while True:
    m = re.search(r'(?:.*?)i(nterest\w{2})(\w)(?:(?<!i\1)(?!=\2).)*', s)
    if not m:
        break
    print(m[0])
    s = s[m.span(1)[0]:]

Отпечатки:

Here is text : My text is so interesting, depending "interestin
nteresting, depending "interesting" meaning of course.

Демо

(?:.*?)i(nterest\w{2})(\w)(?:(?<!i\1)(?!=\2).)*

Строка, которую мы ищем, разбивается на куски:

  1. 'i' соответствует i
  2. (nterest\w{2}) Группа захвата 1 -> interest плюс первые два символа слова нашего совпадения.
  3. (\w) Группа захвата 2 -> третий и последний символ нашего совпадения.

Затем мы сканируем один символ за раз, если предыдущие символы не i плюс группа захвата 1 и следующий символ не является группой захвата 2 :

(?:(?<!i\1)(?!=\2).)*

Затем мы используем местоположение группы захвата 1, чтобы определить, где должно начаться следующее сканирование.

...