Как сопоставить выражение регулярного выражения и получить прецедентные слова - PullRequest
0 голосов
/ 05 января 2019

Я использую регулярное выражение для сопоставления определенных выражений в тексте.

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

Я делаю следующее:

import re
pattern =re.compile(r"(\()([0-9]+(,)?( )?)+(\))")
matches = pattern.findall(content)

совпадений - это список совпадений,

for i,match in enumerate(matches):
    print(i,match)

Пример текста:

Lorem ipsum dolor sit amet (12,16), священник 23, участвующий в элите. Курабитур (45). Vivamus aliquam Velit (46,48,49) в augue faucibus, id eleifend purus egestas. Aliquam vitae mauris cursus, facilisis enim condimentum, vestibulum enim. Praesent

enter image description here

ВОПРОС 1 Как получить список полных совпадений, таких как:

matches=[ "(12,16)", "(45)", "(46,48,49)"]

ВОПРОС 2: как мне получить список с n предшествующими словами полного соответствия? Я пытаюсь разбить текст на слова. Проблема здесь в том, что попадание (12,16) может быть несколько раз в тексте. Вторая проблема при использовании:

mywordlist=text.split(' ') 

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

"ipsum dolor sit amet"         (12,16) 
"adipiscing elit. Curabitur"   (45)
". Vivamus aliquam velit"      (46,48,49)

ПОСЛЕ НЕКОТОРЫХ КОММЕНТАРИЙ: print (спички) дает мне:

matches = pattern.findall(content)
print('the matches are:')
print('type of variable matches',type(matches))
print(matches)

[('(', '16', ',', ')'), ('(', '45', '', ')'), ('(', '49', ',', ')')]

1 Ответ

0 голосов
/ 05 января 2019

Пример кода с измененным регулярным выражением - тест здесь: https://regex101.com/r/mV1l3E/3

import re

regex = r"(\w+ (?=\(\d))(\([\d,]+\))"

test_str = """bla kra tu (34) blaka trutra (33,45) afda
bla kra tu (34) blaka trutra (33,45) afdabla kra tu (34) blaka trutra (33,45) afda 
bla kra tu (34) blaka trutra (33,45) afda""" 

matches = re.findall(regex, test_str, re.MULTILINE)

print(matches) 

for first_matching_group, number_group in matches: 
    print(first_matching_group, "===>", number_group)

Выход:

# matches (each a tuple of both matches
[('kra tu ', '(34)'), ('blaka trutra ', '(33,45)'), ('kra tu ', '(34)'), 
 ('blaka trutra ', '(33,45)'), ('kra tu ', '(34)'), ('blaka trutra ', '(33,45)'), 
 ('kra tu ', '(34)'), ('blaka trutra ', '(33,45)')]


# for loop output
('kra tu ', '===>', '(34)')
('blaka trutra ', '===>', '(33,45)')
('kra tu ', '===>', '(34)')
('blaka trutra ', '===>', '(33,45)')
('kra tu ', '===>', '(34)')
('blaka trutra ', '===>', '(33,45)')
('kra tu ', '===>', '(34)')
('blaka trutra ', '===>', '(33,45)')

Объяснение модели:

(\w+ (?=\(\d))(\([\d,]+\))
--------------============

Две группы в шаблоне, группа ------ ищет 2 слова, разделенные пробелами, не содержащие нескольких слов (\w+), с заглядыванием в открывающую открывающую скобку и одной цифрой (вы можете включить полный второй шаблон здесь, чтобы избежать несовпадений). Второй шаблон ======== ищет круглые скобки + несколько цифр и запятых, за которыми следует закрывающая круглая скобка.

Ссылка на regexr101 https://regex101.com/r/mV1l3E/3/ объясняет это намного лучше и в цвете, если скопировать шаблон в его поле регулярного выражения.

Паттерн не найдет (42) с , а не 2 словами перед ним - вам придется немного поиграться, если это тоже вариант использования.


Edit:

Может быть, немного лучше регулярное выражение: r'((?:\w+ ?){1,5}(?=\(\d))(\([\d,]+\))' - нужно только 1 слово до (https://regex101.com/r/mV1l3E/5/)

...