我有这个字符串
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']
我可以使用模式 <(.*?)>
提取模板的占位符对于正则表达式,但我目前陷入如何从字符串中提取实际替换的问题。我需要一种通用方法,并且不想对模式进行硬编码以匹配完整模板,因为我有很多模板需要检查。有什么聪明的方法可以做到这一点吗?
最佳答案
您可以使用模板动态构建正则表达式。然后将其与任何输入字符串进行匹配。
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'}
关于python - 用于提取占位符匹配的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56348013/