如何使用自定义正则表达式进行多个调用?

问题描述 投票:-2回答:3

编辑:此部分已解决,但是我的代码有最后一个问题,请参阅最后一个答案。

我有一个文本文件,结构如下:

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正在独立工作,但不能一起工作。我应该怎么做?

python regex text multiline multilinestring
3个回答
1
投票

您想要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
  1. ^匹配行的开始。
  2. [a-z.'-]+匹配一个或多个字母,句点,'或-字符。这是一个名称元素
  3. (?:\s+[a-z.'-]+)*匹配一个或多个空格字符,后跟name element。重复0次或更多次。因此,命名组name由1个或多个name elements组成,并由一个或多个空格字符分隔。
  4. [\n匹配换行符。
  5. (?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

0
投票

所以大家好,

感谢您的帮助:此处提供代码

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'),它将显示预期的结果。我认为这与正则表达式有关,我试图在每个新的迭代中分配新的值,但它不是这样。

有人可以帮助我,谢谢!! >>


0
投票

您应使用re.MULTILINE

© www.soinside.com 2019 - 2024. All rights reserved.