Regex рекурсия захваченная строка - PullRequest
3 голосов
/ 20 февраля 2020

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

У меня есть это регулярное выражение:

(?<domain>\w+\.\w+)($|\/|\.)

И Я хочу захватить каждый поддомен рекурсивно. Например, в этой строке:

test1.test2.abc.def

Это выражение захватывает test1.test2 и abc.def, но мне нужно захватить: test1.test2 test2.abc abc.def

Знаете ли вы, есть ли возможность сделать это рекурсивно?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 20 февраля 2020

Может быть после :

(\.|^)(?=(\w+\.\w+))

Go с группой захвата 2

1 голос
/ 20 февраля 2020

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

/(\w+)\.(?=(\w+))/g

Демонстрация .

Редактировать: Регулярное выражение JvdV является более правильным .


Обратите внимание, что \w+ is не будет соответствовать доменам, таким как regex-tester.com, и будет соответствовать недействительно regex_tester.com. [a-zA-Z0-9-]+ ближе к правильному. См. Этот ответ для полного регулярного выражения .


Это проще и надежнее сделать, разбив на . и итерируя по частям попарно. Например, в Ruby ...

"test1.test2.abc.def".split(".").each_cons(2) { |a|
  puts a.join(".")
}

test1.test2
test2.abc
abc.def
0 голосов
/ 20 февраля 2020

Вы можете использовать хорошо известную технику для извлечения перекрывающихся совпадений , но вы не можете полагаться на \b границы, так как они могут совпадать между несловесным / словесным символом и слово / не слово char. Вам нужны однозначные границы слов для контекстов левой и правой руки.

Использование

(?=(?<!\w)(?<domain>\w+\.\w+)(?!\w))

См. Демонстрационную версию regex . Детали:

  • (?= - положительный прогноз, позволяющий проверить каждое место строки и захватить часть строки справа от нее
    • (?<!\w) - слева - граница слова со стороны стороны
    • (?<domain>\w+\.\w+) - группа "домен": 1+ слова, . и 1+ слова
    • (?!\w) - правая граница слова
  • ) - конец внешнего вида.

Другой подход заключается в использовании точек в качестве разделителей слов. Затем используйте

(?=(?<![^.])(?<domain>[^.]+\.[^.]+)(?![^.]))

См. это демонстрационное выражение regex . Отрегулируйте, как считаете нужным.

...