编辑:此部分已解决,但是我的代码有最后一个问题,请参阅最后一个答案。
我有一个文本文件,结构如下:
Name1 (Middlename1) LastName
Birthyear
Name2 (Middlename2) LastName
Birthyear
...
NameN (MiddlenameM) LastName
Birthyear
我正在尝试使用RE自动查找名称和年份,但由于两个信息不在同一行,所以我不知道如何合并这两个RE:
import re
regexp = re.compile( r'(( )*)(?P<name>([a-zA-Z]*)( [a-zA-Z]+)? ROCHE)\n'
r'(( )*)(?P<year>18\d\d)\n'
)
两个RE正在独立工作,但不能一起工作。我应该怎么做?
您想要one正则表达式,它扫描跨越two行的字符串。然后,您想查找连续的匹配项。但首先:
至少在英语国家中,名称可以包含连字符(Anne-Marie),撇号(O'Donnell),句号(John Q. Public)等。因此,我正在使用允许这些字符的正则表达式。同样,人们可能有多个中间名。我想说明的是如何通过名称/年份对进行迭代。您可以自定义实际的正则表达式以满足您自己的特定要求。
正则表达式:
^(?P<name>(?:[a-z.'-]+(?:\s+[a-z.'-]+)*))\n(?P<year>\d{4})$ Flags: re.M|re.I
^
匹配行的开始。[a-z.'-]+
匹配一个或多个字母,句点,'或-字符。这是一个名称元素。(?:\s+[a-z.'-]+)*
匹配一个或多个空格字符,后跟name element。重复0次或更多次。因此,命名组name由1个或多个name elements组成,并由一个或多个空格字符分隔。\n
匹配换行符。(?P<year>\d{4})$
匹配4位数字,后跟行尾或字符串末尾。[MULTILINE标志将^
和$
锚视为特殊,因此除了字符串的开头和结尾,行的开头和结尾之外,它们也匹配。
该代码依赖于re.finditer
查找连续的匹配项:
import re
text = """John Doe
1921
John Q. Public
1987
Anne-Marie Smith
1989
Paul O'Donnell
2001
J. P. Marquand
1893
"""
regexp = re.compile(r"^(?P<name>(?:[a-z.'-]+(?:\s+[a-z.'-]+)*))\n(?P<year>\d{4})$", flags=re.M|re.I)
for m in regexp.finditer(text):
name = m['name']
year = m['year']
# do something with name and year in the second file. Here we are just printing the values.
print(name, year)
打印:
John Doe 1921
John Q. Public 1987
Anne-Marie Smith 1989
Paul O'Donnell 2001
J. P. Marquand 1893
所以大家好,
感谢您的帮助:此处提供代码
import re
text = open("name.txt", "r")
regexp = re.compile(r"^(?P<name>(?:[a-z.'-]+(?:\s+[a-z.'-]+)*))\n(?P<year>\d{4})$", flags=re.M|re.I)
for m in regexp.finditer(text.read()):
name = m['name']
year = m['year']
# do something with name and year in the second file. Here we are just printing the values.
print(name, year)
我的第二个文件的结构如下:
Roger Coekelbergs
1921
Philip Poutou
1921
Jeanne Susette
1893
Louisa Morrel
2001
所以现在我需要创建一个函数,该函数使用与名称相关的年份,并创建一个新的正则表达式来搜索第二个文件中的任何对应关系,因此我们几乎没有匹配项:
text2 = open("name2.txt", "r")
def findmatch(text2, year):
regexp2 = re.compile(f"^(?P<name2>(?:[a-z.'-]+(?:\s+[a-z.'-]+)*))\n(?P<year2>{year})$", flags=re.M|re.I)
matchs = []
for n in regexp2.finditer(text2.read()):
matchs.append(n['name2'])
print(matchs)
findmatch(text2, '1921')
findmatch(text2, '2001')
但是我有一个问题,我不明白为什么,第一个findmatch(text2, '1921')
有效,但是第二个或第三个无效...第二个迭代之后,返回的列表始终为空。它与参数无关,因为如果我仅先执行findmatch(text2, '2001')
,它将显示预期的结果。我认为这与正则表达式有关,我试图在每个新的迭代中分配新的值,但它不是这样。
有人可以帮助我,谢谢!! >>
您应使用re.MULTILINE