Извлекайте различные вариации переносимых имен с помощью регулярных выражений - PullRequest
2 голосов
/ 21 марта 2019

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

    text = 'This is the text where Lord Lee-How and Sir Alex Smith are mentioned.\
     Dame Ane Paul-Law is mentioned too. And just Lady Ball.'
    names = re.compile(r'(Lord|Baroness|Lady|Baron|Dame|Sir) ([A-Z][a-z]+)[ ]?([A-Z][a-z]+)?')
    names_with_titles = list(set(peers.findall(text)))  
    print(names_with_titles)

Текущий вывод:

[('Lord', 'Lee', ''), ('Sir', 'Alex', 'Smith'), ('Dame', 'Ane', 'Paul'), ('Lady', 'Ball', '')]

Требуемый вывод должен быть:

[('Lord', 'Lee-How', ''), ('Sir', 'Alex', 'Smith'), ('Dame', 'Ane', 'Paul-Law'), ('Lady', 'Ball', '')]

Мне удалосьчтобы извлечь дефисные имена с этим шаблоном -

hyph_names = re.compile(r'(Lord|Baroness|Lady|Baron|Dame|Sir) ([A-Z]\w+(?=[\s\-][A-Z])(?:[\s\-][A-Z]\w+)+)')

Но я не могу понять, как их объединить.Буду признателен за вашу помощь!

1 Ответ

2 голосов
/ 21 марта 2019

Вы можете добавить необязательную группу (?:-[A-Z][a-z]+)? к шаблонам именных частей:

(Lord|Baroness|Lady|Baron|Dame|Sir)\s+([A-Z][a-z]+(?:-[A-Z][a-z]+)?)(?:\s+([A-Z][a-z]+(?:-[A-Z][a-z]+)?))?

См. Демонстрационную версию regex

Подробности

  • (Lord|Baroness|Lady|Baron|Dame|Sir) - один из заголовков
  • \s+ - один или несколько пробельных символов
  • ([A-Z][a-z]+(?:-[A-Z][a-z]+)?) - группа захвата # 1:
    • [A-Z][a-z]+ - заглавная буква, за которой следуют 1+ строчные буквы
    • (?:-[A-Z][a-z]+)? - необязательная группа без захвата, соответствующая дефису, а затем заглавная буква, за которой следуют 1+ строчные буквы
  • (?:\s+([A-Z][a-z]+(?:-[A-Z][a-z]+)?))? - необязательная группа без захвата:
    • \s+ - 1+ пробелов
    • ([A-Z][a-z]+(?:-[A-Z][a-z]+)?) - группа захвата № 2 стот же шаблон, что и в группе 1.

Вы можете построить его в Python 3.7 как

title = r'(Lord|Baroness|Lady|Baron|Dame|Sir)'
name = r'([A-Z][a-z]+(?:-[A-Z][a-z]+)?)'
rx = rf'{title}\s+{name}(?:\s+{name})?'    

В старых версиях

rx = r'{0}\s+{1}(?:\s+{1})?'.format(title, name) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...