регулярные выражения Python, как извлечь самые длинные из перекрывающихся групп - PullRequest
3 голосов
/ 14 мая 2010

Как я могу извлечь самую длинную из групп, которые начинаются одинаково

Например, из заданной строки я хочу извлечь самое длинное соответствие либо CS, либо CSI.

Я попробовал это "(CS | CSI). *", И он вернет CS, а не CSI, даже если CSI доступен.

Если я сделаю "(CSI | CS). *", Тогда я получу CSI, если это совпадение, поэтому я думаю, что решение состоит в том, чтобы всегда размещать короче перекрывающихся групп после более длинной.

Есть ли более ясный способ выразить это с помощью re? почему-то кажется странным, что результат зависит от порядка, в котором вы связываете группы.

Ответы [ 4 ]

3 голосов
/ 14 мая 2010

Нет, именно так оно и работает, по крайней мере, в таких регулярных выражениях Perl, как Python, JavaScript, .NET и т. Д.

http://www.regular -expressions.info / alternation.html

0 голосов
/ 14 мая 2010

Как говорит Алан, шаблоны будут совпадать в указанном вами порядке.

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

>>> '|'.join(sorted('cs csi miami vice'.split(), key=len, reverse=True))
'miami|vice|csi|cs'
0 голосов
/ 14 мая 2010

аналогичная функциональность присутствует в редакторе vim («последовательность необязательно совпадающих атомов»), где, например, col\%[umn] соответствует col в color, colum в columbus и полном column.

Я не в курсе, есть ли аналогичные функции в Python Re, для этого вы можете использовать вложенные анонимные группы, за которыми следует квантификатор ?:

>>> import re
>>> words = ['color', 'columbus', 'column']
>>> rex = re.compile(r'col(?:u(?:m(?:n)?)?)?')
>>> for w in words: print rex.findall(w)
['col']
['colum']
['column']
0 голосов
/ 14 мая 2010

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

import re

string_to_look_in = "AUHDASOHDCSIAAOSLINDASOI"
string_to_match = "CSIABC"

re_to_use = "(" + "|".join([string_to_match[0:i] for i in range(len(string_to_match),0,-1)]) + ")"

re_result = re.search(re_to_use,string_to_look_in)

print string_to_look_in[re_result.start():re_result.end()]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...