正则表达式,用于提取占位符匹配

时间:2019-05-28 18:20:15

标签: python regex regex-lookarounds regex-group

我有这个字符串

template = "Hello my name is <name>, I'm <age>."

我想测试我的字符串是否与该模板匹配,并且可以使用任何东西代替占位符。占位符以<place holder here>这样的括号开头和结尾。例如,此字符串将匹配

string = "Hello my name is John Doe, I'm 30 years old."

我还想提取替换占位符的字符串部分。对于上面的示例,我想获取列表:

['John Doe', '30 years old']

我能够使用模式<(.*?)>提取正则表达式的模板的占位符,但是我目前仍停留在如何从字符串中提取实际替换项上。我需要一种通用方法,并且我不想对模式进行硬编码以匹配整个模板,因为我要检查很多模板。有聪明的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用模板动态构建正则表达式。然后将其与任何输入字符串匹配。

import re

template = "Hello my name is <name>, I'm <age>."
pattern = "^" + re.escape(template) + "$"
pattern = re.sub("<[^>]+>", "(?P\g<0>.*)", pattern)
regex = re.compile(pattern, re.DOTALL)

string = "Hello my name is John Doe, I'm 30 years old."
match = regex.match(string)

match.group(0)
#=> "Hello my name is John Doe, I'm 30 years old."
match.group("name")
#=> 'John Doe'
match.group("age")
#=> '30 years old'
match.groups()
#=> ('John Doe', '30 years old')

对模板的唯一限制是应使用有效的正则表达式组名称。

您可以通过不使用命名的正则表达式组来取消此操作。

# replacing
pattern = re.sub("<[^>]+>", "(?P\g<0>.*)", pattern)
# with
pattern = re.sub("<[^>]+>", "(.*)", pattern)

通过在模板中交叉引用占位符将其组合起来,您将拥有更多的命名选项。

placeholders = re.findall("<[^>]+>", template)
placeholders = list(map(lambda match: match[1:-1], placeholders))

dict(zip(placeholders, match.groups()))
#=> {'name': 'John Doe', 'age': '30 years old'}

答案 1 :(得分:0)

如果所需的输出后面是问题中提到的精确标点符号,我们可以简单地使用类似于以下内容的表达式:

is\s(.+?),|([0-9].+)\.

DEMO

测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"is\s(.+?),|([0-9].+)\."

test_str = "Hello my name is John Doe, I'm 30 years old."

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

enter image description here