在 "Mr." 或 "Mrs." 之前拆分字符串

Splitting a string before "Mr." or "Mrs."

我有一个文件,其中包含如下所示的字符串:

"TextMr. XxxxxMrs. YyyyyMrs. ZzzzzTextWordLady ZzzzzMr. Xxxxx"

现在,我想用 Python 拆分它,这样它看起来像这样:

['Text', 'Mr. Xxxxx', 'Mrs. Yyyyy', 'Mrs. Zzzzz', 'Text', 'Word', 'Lady Zzzzz', 'Mr. Xxxxx']

目前我使用的是:

test2 = re.sub( r"([A-Z])", r" ", data).split()

这给了我:

['Text', 'Mr.', 'Xxxxx', 'Mrs.', 'Yyyyy', 'Mrs.', 'Zzzzz', 'Text', 'Word', 'Lady', 'Zzzzz', 'Mr.', 'Xxxxx']

我知道这可能非常简单,并且还阅读了我能找到的关于正则表达式和标题的所有主题,但似乎没有人遇到同样的问题。如果有人能给我指出正确的方向并告诉我哪里做错了,我会很高兴(有一次,我花了一个小时盯着一个不起作用的代码片段,结果发现我只是忘记了 *) 因为我很想了解正则表达式。

(.+?)(?=Mr\.|Mrs\.|$|(?<! )[A-Z])

尝试this.See demo.Grab 捕获。

https://regex101.com/r/sJ9gM7/59#python

import re
p = re.compile(r'(.+?)(?=Mr\.|Mrs\.|$|(?<! )[A-Z])', re.MULTILINE)
test_str = "TextMr. XxxxxMrs. YyyyyMrs. ZzzzzTextWordLady ZzzzzMr. Xxxxx"

re.findall(p, test_str)

我建议您创建一个列表,其中包含所有可能的标题,这些标题可以先命名:

>>> titles = "Mr\. Mrs\. Lady Sir".split()
['Mr\.', 'Mrs\.', 'Lady', 'Sir']

然后您可以使用它们为任何这些标题创建正则表达式,然后是 space。

>>> title_opt = "(?:(?:" + "|".join(titles) + ") )?"
'(?:(?:Mr\.|Mrs\.|Lady|Sir) )?'

然后使用这些标题后跟一个单词来查找所有名称和单词。

>>> re.findall(title_opt + "[A-Z][a-z]+", text)
['Text', 'Mr. Xxxxx', 'Mrs. Yyyyy', 'Mrs. Zzzzz', 'Text', 'Word', 'Lady Zzzzz', 'Mr. Xxxxx']

或者,根据您自己的方法,一旦您拥有名称、单词和标题的列表,您可以使用迭代器将标题连接到迭代器中的 next 单词。

>>> names = ['Text', 'Mr.', 'Xxxxx', 'Mrs.', 'Yyyyy', 'Mrs.', 'Zzzzz', 'Text', 'Word', 'Lady', 'Zzzzz', 'Mr.', 'Xxxxx']
>>> titles = set("Mr. Mrs. Lady Sir".split())
>>> iterator = iter(names)
>>> [s if s not in titles else s + " " + next(iterator) for s in iterator]
['Text', 'Mr. Xxxxx', 'Mrs. Yyyyy', 'Mrs. Zzzzz', 'Text', 'Word', 'Lady Zzzzz', 'Mr. Xxxxx']