Python 2.6+ str.format() 和正则表达式

问题描述 投票:0回答:3

使用

str.format()
是 Python 2.6 和 Python 3 中格式化字符串的新标准。在将
str.format()
与正则表达式一起使用时,我遇到了问题。

我编写了一个正则表达式,用于返回指定域以下一级的所有域或指定域以下 2 级的任何域,如果下面的第二级是 www...

假设指定的域名是delivery.com,我的正则表达式应该返回a.delivery.com,b.delivery.com,www.c.delivery.com ...但它不应该返回x.a.delivery.com。

import re

str1 = "www.pizza.delivery.com"
str2 = "w.pizza.delivery.com"
str3 = "pizza.delivery.com"

if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}delivery.com$', str1): print 'String 1 matches!'
if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}delivery.com$', str2): print 'String 2 matches!'
if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}delivery.com$', str3): print 'String 3 matches!'

运行此命令应该给出结果:

String 1 matches!
String 3 matches!

现在,问题是当我尝试使用str.format动态替换delivery.com时...

if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}{domainName}$'.format(domainName = 'delivery.com'), str1): print 'String 1 matches!'

这似乎失败了,因为

str.format()
期望
{3}
{1}
作为函数的参数。 (我假设)

我可以使用 + 运算符连接字符串

'^(w{3}\.)?([0-9A-Za-z-]+\.){1}' + domainName + '$'

问题归结为,当字符串(通常是正则表达式)中包含“

{n}
”时,是否可以使用str.format()

python regex format string-formatting
3个回答
41
投票

您首先需要格式化字符串,然后使用正则表达式。将所有内容都放在一行中确实不值得。通过加倍大括号来完成转义:

>>> pat= '^(w{{3}}\.)?([0-9A-Za-z-]+\.){{1}}{domainName}$'.format(domainName = 'delivery.com')
>>> pat
'^(w{3}\\.)?([0-9A-Za-z-]+\\.){1}delivery.com$'
>>> re.match(pat, str1)

此外,

re.match
在字符串的开头匹配,如果您使用
^
,则不必放置
re.match
,但是,如果您使用
^
,则需要
re.search

请注意,正则表达式中的

{1}
相当多余。


16
投票

根据 文档,如果您需要文字

{
}
才能在格式化操作中幸存下来,请在原始字符串中使用
{{
}}

'^(w{{3}}\.)?([0-9A-Za-z-]+\.){{1}}{domainName}$'.format(domainName = 'delivery.com')

0
投票

不幸的是,对于我的情况来说,它不能以这种方式工作,最后我使用了像这样的串联

pattern='{'+Acc[0]+'}(\.\d+)?'
其中 Acc[0] 是我的正则表达式中的变量项。

我尝试了以下失败的格式。我分享给你也许你感兴趣(我使用python 3.7):

pattern='{{Acc[0]}}(\.\d+)?'
pattern='{{ID}}(\.\d+)?'.format(ID = Acc[0])
pattern='{{1}}(\.\d+)?'.format(ID = Acc[0])
pattern="{{}}(\.\d+)?".format(Acc[0])
pattern=fr"{{Acc[0]}}(\.\d+)?"
pattern = "%s(\\.\d+)?" % (Acc[0])
© www.soinside.com 2019 - 2024. All rights reserved.