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

wsxa1bj1  于 12个月前  发布在  Python
关注(0)|答案(3)|浏览(122)

在Python 2.6和Python 3中,使用str.format()是格式化字符串的新标准。在正则表达式中使用str.format()时,我遇到了一个问题。
我写了一个正则表达式,返回所有低于指定域一级的域,或者任何低于指定域两级的域,如果下面的第二级是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.exe动态替换www.example.com时,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()

pqwbnv8z

pqwbnv8z1#

你首先需要格式化字符串,然后使用正则表达式。把所有的东西都放在一行中真的不值得。转义是通过双花括号来完成的:

>>> 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,则需要^
请注意,regex中的{1}是相当冗余的。

ifsvaxew

ifsvaxew2#

根据文档,如果您需要文字{}来保存格式化操作,请在原始字符串中使用{{}}

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

字符串

iqih9akk

iqih9akk3#

不幸的是,在我的例子中,它不能以这种方式工作,最后我使用了像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])

字符串

相关问题