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