2014-11-03 2 views
-2

У меня есть 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) 

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

+0

Вам нужно использовать регулярное выражение? Я бы, наверное, просто разделил строку на строки и просто работал оттуда. –

+0

какой выход вы хотите точно? –

+0

Регулярные выражения Python по умолчанию не охватывают несколько строк. Вам нужно установить параметр [re.DOTALL] (https://docs.python.org/release/3.1.3/library/re.html#re.DOTALL) в findall – sirlark

ответ

1

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

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

Regular expression visualization

Debuggex Demo

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

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

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

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

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

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

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

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

... Я бы переместить \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)) 
0

Если вы настроить его, что-то вроде этого
(\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 
0

Я попытался как этот

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

выход:

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

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

+0

По какой-то причине OP, по-видимому, хочет 2 пары на смежных линиях. В любом случае, задал тот же вопрос, но другая неделя. Я впервые заметил вопрос о месяцем назад разных пользователей. – sln

+0

Я хочу сгенерировать bigram –

+0

Возможно, регулярное выражение не является правильным aproach для этой задачи, какой другой aproach я могу использовать ?. Просто разбить строку на строки может быть лучше? –

Смежные вопросы