Python Regex Capturing Group - PullRequest
       4

Python Regex Capturing Group

1 голос
/ 31 мая 2019
string1 = "abcdbcdbcde"

Я хочу извлечь строку1 на три части: (первая часть и третья часть могут быть пустой строкой)

первая часть:

вторая часть (повторения некоторой строки): bcdbcdbcd

третья часть: e

import re

string1 = "abcdbcdbcde"
m = re.match("(.*)(.+){2,}(.*)", string1)
print m.groups()[0], m.groups()[1], m.groups()[2]

Потому что приведенный выше код не работает.

Как я знаю, оператор скобок может использоваться в качестве захвата RegExгруппа или ссылка на шаблон.Как использовать оператор скобок в этих 2 случаях одновременно?

Что я хочу:

m.groups()[0] = "a"
m.groups()[1] = "bcdbcdbcd"
m.groups()[2] = "e"

Ответы [ 4 ]

2 голосов
/ 31 мая 2019

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

^.?(.+)\1+.?$

Regex demo

Или, если вы хотите захватить всегруппы:

^(.?)((.+)\3+)(.?)$
  • ^ Начало строки
  • (.?) Группа 1, опционально соответствует любому символу
  • ( Группа 2
    • (.+)\3+ Группа 3, сопоставить любой символ, за которым следует обратная ссылка на группу 3 с повторением 1+ гимнов
  • ) Закрыть группу 3
  • (.?)Группа 4, по выбору соответствует любому символу
  • $ Конец строки

Regex demo

0 голосов
/ 31 мая 2019

Мое мнение о проблеме:

import re

def match(s, m):
    m = re.match("(.*?)?((?:" + m + "){2,})(.*?)?$", s)
    return (m.groups()[0], m.groups()[1], m.groups()[2]) if m else (None, None, None)

print(match("abcdbcdbcde", "bcd"))
print(match("bcdbcdbcd", "bcd"))
print(match("abcdbcdbcd", "bcd"))
print(match("bcdbcdbcde", "bcd"))
print(match("axxbcdbcdxxe", "bcd"))
print(match("axxbcdxxe", "bcd")) # only one bcd in the middle

Печать:

('a', 'bcdbcdbcd', 'e')
('', 'bcdbcdbcd', '')
('a', 'bcdbcdbcd', '')
('', 'bcdbcdbcd', 'e')
('axx', 'bcdbcd', 'xxe')
(None, None, None)
0 голосов
/ 31 мая 2019

Следующее регулярное выражение должно работать (предостережение ниже):

^(.*?)((.+?)\3+)(.*)

Пояснение:

^      # Start of string
(.*?)  # Match any number of characters, as few as possible, until...
(      # (Start capturing group #2)
 (.+?) # ... a string is matched (and captured in group #3)
 \3+   # that is repeated at least once.
)      # End of group #2
(.*)   # Match the rest of the string

Проверьте это живите на regex101.com .

Предупреждение: если строка длинная и не имеет каких-либо очевидных повторов, это будет иметь очень плохие характеристики производительности (я думаю, что O(n!)), поскольку движок регулярных выражений должен проверять каждую перестановку подстрок , См катастрофический откат .

0 голосов
/ 31 мая 2019

Я думаю, что невозможно точно соответствовать вашим требованиям, так как требуется больше групп захвата (по крайней мере, для повторения совпадения той же строки с \1).

Но вы можете попробовать (\w+)((\w+)\3+)(\w+)

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

Пояснение:

\w+ - соответствует одному или нескольким символам слова

\3+ - совпадает строка, захваченная в третьей группе захвата, один или несколько раз

Демо

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