Регулярное выражение перекрытия включения - PullRequest
0 голосов
/ 01 января 2019

Предположим, я хотел бы найти набор тегов в строке, где некоторые теги могут быть подстроки других тегов.Например, я хотел бы найти теги ["UC", "UC Berkeley", "Berkeley"] в тексте "Он посещал UC Berkeley в прошлом году".Я ожидаю получить все три тега, чтобы показать.Тем не менее, когда я запускаю это в Python, я получаю только «UC» и «Berkeley»:

import re
string = "He attended UC Berkeley last year."
compiled_regexp = re.compile("UC|UC Berkeley|Berkeley", re.IGNORECASE)

re.findall(compiled_regexp, string)
# result is: ['UC', 'Berkeley']

Как я могу получить все три тега для отображения?


MyФактический вариант использования включает в себя десятки тысяч тегов, многие из которых являются префиксами других тегов.Есть также теги, которые являются префиксами других тегов, которые сами являются префиксами других тегов и т. Д. (Например, ["UC", "UCB", "UCBA" ...]). Было бы невозможно вручную создать группы захвата для всехиз префиксов других тегов.Есть ли лучший способ сделать это?


Обновление:
Я решил сделать следующее:
Сначала я нахожу все теги, которые являются префиксамидругих тегов.Затем я создаю два отдельных регулярных выражения, одно для тегов с префиксами, а другое для тегов без префиксов.Наконец, я ищу строку с обоими регулярными выражениями и объединяю результаты.

Ответы [ 2 ]

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

Решение для небольшого количества целевых строк

Если у вас есть только несколько целевых строк, тогда все еще возможно вручную создать шаблон регулярного выражения и выполнить поиск следующим образом:

import re
string = "He attended UC Berkeley last year."
compiled_regexp = re.compile(r"((UC) (Berkeley)|UC|Berkeley)", re.IGNORECASE)

matches = re.findall(compiled_regexp, string)
print(matches)

дает в качестве вывода:

[('UC Berkeley', 'UC', 'Berkeley')]

Дополнительные пояснения по этому шаблону регулярных выражений см. regex101 .

Общее решение

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

string = "He attended UC Berkeley last year."
targets = ["UC Berkeley", "UC", "Berkeley"]
string_lower = string.lower()
found = [target for target in targets if target.lower() in string_lower]
print(found)

, которая дает в качестве вывода:

['UC Berkeley', 'UC', 'Berkeley']
0 голосов
/ 01 января 2019

re.findall () не поддерживает перекрывающиеся совпадения и «UC» перекрываются с «UC Berkley», а также перекрываются между «Berkley» и «UC Berkley».

...