Проблемы с регулярным выражением?

У меня есть very_largeString который содержит список слов и некоторый id. Я хотел бы извлечь все слова (с их идентификаторами), которые имеют RG и AQ которые морфологически происходят последовательно и распечатывают остальную часть идентификатора. Вывод - это просто слово и связанный с ним идентификатор, например: [('word','id'),('word','id')]

very_largeString= ''' Hola hola I 1
compis compis NCMS000 0.500006
! ! Fat 1

No no RN 0.998045
sabía saber VMII3S0 0.592869
como como CS 0.999289
se se P00CN000 0.465639
ponía poner VMII3S0 0.65
una uno DI0FS0 0.951575
lavadora lavadora NCFS000 0.414738
hasta hasta SPS00 0.957698
que que PR0CN000 0.562517
conocí conocer VMIS1S0 1
esta este DD0FS0 0.986779
y y CC 0.999962
muy muy RG 1
sencilla malo AQ0MP0
es ser VSIP3S0 1
que que CS 0.437483
es ser VSIP3S0 1
muy muy RG 1
sencilla sencillo AQ0FS0 1
de de SPS00 0.999984
utilizar utilizar VMN0000 1
! ! Fat 1 
'''

Это будет желаемый результат, так как они имеют в начале идентификатора символы RG и AQ, тогда я хочу вернуть полный id, например:

[('muy', RG), ('sencillo', 'AQ0FS0'),('muy'),('malo','AQ0MP0')]

Проблема в том, что я получаю нулевой вывод. Это то, что я пробовал:

result = re.findall("(\S+)\s+(RG\S+).*\n.*\s(\S+)\s+(AQ\S+)",very_largeString)

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

3 ответа

Основная проблема заключается в том, что RG\S+ не будет соответствовать RG 1, потому что это пространство не соответствует одному или нескольким непространственным символам. Думаю, вы хотели \S+ там? (Или, может быть, \S*? Но я не вижу возможных RG1 -type. Или, может быть, вообще ничего, потому что я не уверен, что какой-нибудь под-шаблон пытается здесь сделать?)

(\S+)\s+(RG\s+).\n.*\s(\S+)\s+(AQ\S+)

Демоверсия Debuggex

Однако это не дает желаемого результата. Что это дает вам, так это:

[('muy', 'RG ', 'malo', 'AQ0MP0'), ('muy', 'RG ', 'sencillo', 'AQ0FS0')]

'RG ' довольно очевиден - вы пытаетесь сопоставить что-то обязательное после RG, и единственное, что когда-либо приходит после RG - это пространство, так что еще вы могли бы получить? "

Вам также кажется, что нужно совместить первую и вторую строки отдельно - что можно сделать, но только с ужасно сложным выражением с lookaheads и lookbehinds, и намного проще просто перепрограммировать список.

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

И, наконец, по какой-то причине вы хотите, чтобы вторая пара соответствовала просто ('muy') а не ('muy', 'RG'), которая (a) не имеет никакого смысла, потому что ('muy') а не 1-элементный кортеж, это просто строка 'muy', и (б) я понятия не имею, как вы ожидаете совпадения двух вещей в первый раз, но только с одним и тем же шаблоном и той же строкой второй время.

Предполагая, что большинство ваших требований на самом деле не реально, и единственное, что вы хотите сделать, это перегруппировать их с 4s на 2s, например:

[('muy', 'RG'), ('malo', 'AQ0MP0'), ('muy', 'RG'), ('sencillo', 'AQ0FS0')]

... Я переместил \S+ из регулярного выражения и \S+ результаты из групп по 4 в группы из 2, например:

result = re.findall(r"(\S+)\s+(RG)\s+.*\n.*\s(\S+)\s+(AQ\S+)",very_largeString)
flattened = (x for y in result for x in y)
paired = list(zip(flattened, flattened))


Я так пробовал

re.findall('(\w+\s+)(RG\w*|AQ\w*)',very_largeString)

вывод:

[('muy ', 'RG'), ('malo ', 'AQ0MP0'), ('muy ', 'RG'), ('sencillo ', 'AQ0FS0')]

если вы хотите удалить дублирование, вы можете использовать set


Если вы его настроите, что-то вроде этого (\S+)\S+(RG\S*).*\n.*[^\S\n](\S+)[^\S\n]+(AQ\S*) будет получать то, что ваш ожидаемый результат.

( \S+ ) # (1)
 \s+ 
 ( RG \S* ) # (2)
 .* \n 
 .* [^\S\n] 
 ( \S+ ) # (3)
 [^\S\n]+ 
 ( AQ \S* ) # (4)

Вывод:

** Grp 0 - ( pos 358 , len 29 ) 
muy RG 1
sencilla malo AQ0MP0 
 ** Grp 1 - ( pos 358 , len 3 ) 
muy 
 ** Grp 2 - ( pos 362 , len 2 ) 
RG 
 ** Grp 3 - ( pos 376 , len 4 ) 
malo 
 ** Grp 4 - ( pos 381 , len 6 ) 
AQ0MP0 

------------------------

 ** Grp 0 - ( pos 446 , len 33 ) 
muy RG 1
sencilla sencillo AQ0FS0 
 ** Grp 1 - ( pos 446 , len 3 ) 
muy 
 ** Grp 2 - ( pos 450 , len 2 ) 
RG 
 ** Grp 3 - ( pos 464 , len 8 ) 
sencillo 
 ** Grp 4 - ( pos 473 , len 6 ) 
AQ0FS0

licensed under cc by-sa 3.0 with attribution.