шаблон регулярного выражения включает в себя альфа, специальные, числовые - PullRequest
1 голос
/ 21 марта 2020

Вот мои предложения: например:

это первое: пример 234 -

это второе (пример) 345 1

это мой третий пример (456 ) 3

ожидаемый результат:

['this is first: example', 234, -]
['this is second (example)', 345, 1]
['this is my third example', (456), 3]

Я устал использовать python, токен слова nltk и токен предложения, split () и

str1 = re.compile('([\w: ]+)|([0-9])') str1.findall('my above examples')

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

1 Ответ

1 голос
/ 21 марта 2020

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

^(.*) ([\d()]+) ([-\d])

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

В коде:

regex = r"^(.*) ([\d()]+) ([-\d])"
matches = re.findall(regex, your_text, re.MULTILINE)
print(matches)

Вывод:

[('this is first: example', '234', '-'), 
('this is second (example)', '345', '1'), 
('this is my third example', '(456)', '3')]

Редактировать

Вышеупомянутый шаблон работает хорошо, если вы знаете, сколько групп чисел ожидать в конце. Однако, если это число является переменным, вам нужно создать общее число повторяющихся необязательных групп чисел, например, (?:\d+)?, с ожиданием количества значений, которое вам нужно будет сопоставить, но это громоздко и может не соответствовать всем требованиям up.

Таким образом, было бы лучше собрать все числа, встречающиеся в источнике, в один блок и затем разбить его. Для этого мы сопоставим начало строки с ленивым квантификатором, чтобы сопоставить все доступные группы чисел в конце строки, которые мы запишем в одну. Например:

^(.*?)((?: [-\d()]+)+)$

См. regex demo .

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

import re

test_str = (
    "this is first: example 234 -\n"
    "this is second (example) 345 1\n"
    "this is my third example (456) 3\n"
    "this is the fourth example (456) 4 12\n"
    "this is the fifth example 300 1 16 200 (2) 18")

regex = r"^(.*?)((?: [-\d()]+)+)$"
matches = re.findall(regex, test_str, re.MULTILINE)
captures = [(a, b.split()) for (a, b) in matches]

print(captures)

Вывод:

[
  ('this is first: example', ['234', '-']), 
  ('this is second (example)', ['345', '1']), 
  ('this is my third example', ['(456)', '3']), 
  ('this is the fourth example', ['(456)', '4', '12']), 
  ('this is the fifth example', ['300', '1', '16', '200', '(2)', '18'])
]
...