我目前正在努力掌握Python中的regex技能。我俩都不是专家。也许我使用了错误的正则表达式术语,这就是为什么找不到答案的原因。如果是这种情况,请道歉。
我根据下面的代码创建了一个测试字符串和两个不同的正则表达式:
teststring = "This is just a string of literal text with some 0987654321 and an issue in it"
reg = re.compile(r"([0-9]{3})*",re.DEBUG)
outSearch = reg.search(teststring)
print "Test with ([0-9]{3})*"
if outSearch:
print "groupSearch = " + outSearch.group()
print
reg = re.compile(r"([0-9]{3})+",re.DEBUG)
outSearch = reg.search(teststring)
print "Test with ([0-9]{3})+"
if outSearch:
print "groupSearch = " + outSearch.group()
此test-cde结果如下:
max_repeat 0 4294967295
subpattern 1
max_repeat 3 3
in
range (48, 57)
Test with ([0-9]{3})*
groupSearch =
max_repeat 1 4294967295
subpattern 1
max_repeat 3 3
in
range (48, 57)
Test with ([0-9]{3})+
groupSearch = 098765432
现在有趣的部分:我希望两个正则表达式都将返回相同的结果。例如,我使用([0-9] {3})+获得的结果。当我使用([0-9] {3})*时,正则表达式与测试字符串匹配,但outSearch.group()为空。有人可以解释我为什么吗?
顺便说一句。这两个正则表达式都没有实际用途,我只是想了解正则表达式在Python中的工作方式。
答案 0 :(得分:1)
您的第一个代码使用*
进行重复-这意味着它将与上一组的零个或多个匹配。但是,当您使用+
重复时,至少需要 次。因此,仅包含一个可选组的正则表达式将首先匹配字符串的非常开头,如果该组不接受的第一个字符,则根本不匹配任何字符字符串。如果您检查每个匹配项的start()
和end()
,这将更加清晰:
teststring = "some 0987654321"
reg = re.compile(r"([0-9]{3})*",re.DEBUG)
outSearch = reg.search(teststring)
print("Test with ([0-9]{3})*")
if outSearch:
print ("groupSearch = " + outSearch.group() + ' , ' + str(outSearch.start()) + ' , ' + str(outSearch.end()))
reg = re.compile(r"([0-9]{3})+",re.DEBUG)
outSearch = reg.search(teststring)
print("Test with ([0-9]{3})+")
if outSearch:
print ("groupSearch = " + outSearch.group() + ' , ' + str(outSearch.start()) + ' , ' + str(outSearch.end()))
输出:
Test with ([0-9]{3})*
groupSearch = , 0 , 0
Test with ([0-9]{3})+
groupSearch = 098765432 , 5 , 14
(第一个正则表达式的匹配从索引0开始,到索引0结束-空字符串)
这不是Python独有的-几乎在任何地方都可以预期这种行为:
https://regex101.com/r/BwMWTq/1
(点击以查看其他语言-查看所有语言(不仅是Python)如何在索引0处开始和结束它们的匹配)
答案 1 :(得分:0)
在正则表达式中:
+
:匹配上一个令牌的一个或多个 *
:匹配上一个令牌的零个或多个 现在:
([0-9]{3})+
将匹配一个或多个时间(+
)3个连续数字([0-9]{3}
),因此它在主要匹配组(即组0)中包含9个数字- 098765432,忽略0987654321的最后1个,即匹配范围从索引48到56(teststring[48:57]
)。您也可以使用span()
对象的SRE_Match
方法进行检查,例如outSearch.span()
([0-9]{3})*
将匹配零个或多个时间(*
)3个连续数字;因为它也可以匹配零时间,所以它匹配字符串的开头并在此处停止,从而将空字符串作为主要匹配组的输出,即匹配范围从字符串索引0到0