Как найти строку и подстроку в предложениях - PullRequest
0 голосов
/ 08 июля 2019

Я пытаюсь найти элементы (один из которых является подстрокой другого) в предложениях с регулярным выражением, но он всегда находит подстроку.Например, есть два элемента [«Герцог», «Герцог А»] и несколько предложений:

Герцог

Герцог - это фильм.

Как фильм «Герцог?»

«Герцог А.»

«Герцог А.» - это фильм.

Как фильм «Герцог А.»?

Что мне нужно после нахождения локаций:

The_Duke

The_Duke - это фильм.

Как выглядит фильм The_Duke?

The_Duke_of_A

The_Duke_of_A - это фильм.

Как фильм The_Duke_of_A?

Код, который я пробовал:

for sent in sentences:
    for item in ["The Duke", "The Duke of A"]:
        find = re.search(r'{0}'.format(item), sent)
        if find:
           sent = sent.replace(sent[find.start():find.end()], item.replace(" ", "_"))    

Но я получил:

The_Duke

The_Duke - это фильм.

Как фильм The_Duke?

The_Duke ofA

The_Duke of A - это фильм.

Как выглядит фильм The_Duke of A?

Изменение позиции элементов в списке не подходит вмой случай, так как у меня большой список (более 10 000 наименований).

Ответы [ 4 ]

1 голос
/ 08 июля 2019

Вы можете использовать re.sub, а repl может быть функцией, поэтому просто замените пробелы в результатах.

import re

with open("filename.txt") as sentences:
    for line in sentences:
        print(re.sub(r"The Duke of A|The Duke",
                     lambda s: s[0].replace(' ', '_'),
                     line))

В результате:

The_Duke

The_Duke is a movie.

How is the movie The_Duke?

The_Duke_of_A

The_Duke_of_A is a movie.

How is the movie The_Duke_of_A?
0 голосов
/ 08 июля 2019

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

data = '''The Duke
The Duke is a movie.
How is the movie The Duke?
The Duke of A
The Duke of A is a movie.
How is the movie The Duke of A?'''

terms = ["The Duke", "The Duke of A"]

import re

to_change = []
for t in terms:
    for g in re.finditer(t, data):
        to_change.append((g.start(), g.end()))

for (start, end) in to_change:
    data = data[:start] + re.sub(r'\s', r'_', data[start:end]) + data[end:]

print(data)

Отпечатки:

The_Duke
The_Duke is a movie.
How is the movie The_Duke?
The_Duke_of_A
The_Duke_of_A is a movie.
How is the movie The_Duke_of_A?
0 голосов
/ 08 июля 2019

Поменяйте местами «герцог А» и «герцог» в строке:

for item in ["The Duke", "The Duke of A"]:

становится

for item in ["The Duke of A", "The Duke"]:
0 голосов
/ 08 июля 2019

То, что вы делаете, сначала ищет «Герцога». Если вы нашли какое-либо совпадение, вы заменили его на «The_Duke». Теперь второй проход цикла ищет «Герцога А», но вы не можете найти совпадения, потому что вы изменили его ранее.

Это должно работать.

for sent in sentences:
for item in ["The Duke of A", "The Duke"]:
    find = re.search(r'{0}'.format(item), sent)
    if find:
       sent = sent.replace(sent[find.start():find.end()], item.replace(" ", "_"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...