【发布时间】:2009-10-16 09:00:34
【问题描述】:
我明白了
* = "zero or more"
? = "zero or more" ...what's the difference?
另外,?:
【问题讨论】:
-
您似乎很难找到任何教程。您需要搜索引擎方面的帮助吗?
我明白了
* = "zero or more"
? = "zero or more" ...what's the difference?
另外,?:
【问题讨论】:
正如 Manu 已经说过的,? 的意思是“零次或一次”。与{0,1}相同。
?: 可能是指(?:X),其中 X 是其他字符串。这被称为“非捕获组”。
通常,当您将括号括起来时,会将与这些括号匹配的内容分组。例如,正则表达式 .(.).(.) 匹配任意 4 个字符(换行符除外)并将第二个字符存储在组 1 中,将第四个字符存储在组 2 中。但是,当您这样做时:.(?:.).(.) 只有第四个字符存储在组中1、(?:.) 之间的所有内容都匹配,但不是“记住”。
一个小演示:
import re
m = re.search('.(.).(.)', '1234')
print m.group(1)
print m.group(2)
# output:
# 2
# 4
m = re.search('.(?:.).(.)', '1234')
print m.group(1)
# output:
# 4
您可能会问自己:“为什么要使用这个非捕获组?”。好吧,有时,您想在两个字符串之间进行 OR,例如,您想匹配字符串“www.google.com”或“www.yahoo.com”,您可以这样做:www\.google\.com|www\.yahoo\.com,但更短当然是:www\.(google|yahoo)\.com。但是,如果您不打算对该组捕获的内容(字符串“google”或“yahoo”)做一些有用的事情,那么您最好使用非捕获组:www\.(?:google|yahoo)\.com。当正则表达式引擎不需要“记住”子字符串“google”或“yahoo”时,您的应用程序/脚本将运行得更快。当然,相对较小的字符串不会有太大区别,但是当您的正则表达式和字符串变大时,它可能会。
有关使用非捕获组的更好示例,请参阅下面 Chris Lutz 的评论。
【讨论】:
/(\w+)?\s+(\w+)/可能有一组或两组,如果不检查第二个是否存在,我们不知道哪个是哪个。如果我们知道我们不需要第一组(基本上我们只是确保它存在),我们可以使用/(?:\w+)?\s+(\w+)/,然后我们知道我们想要的数据总是在第一组中。(替换\w+和@ 987654335@ 使用更复杂的正则表达式来获得一个合理的真实示例。)
?:
如果这确实是你的书所说的,那么我建议你买一本更好的书。
在括号内(更准确地说:在左括号之后),? 有另一个含义。它启动了一组 options ,它们仅计入括号的范围。 ?: 是这些选项的特例。要理解这种特殊情况,您必须首先知道括号创建捕获组:
a(.)c
这是一个正则表达式,匹配任何以a 开头并以c 结尾的三字母字符串。中间字符(或多或少)是任意的。既然你把它放在括号里,你可以捕获它:
m = re.search('a(.)c', 'abcdef')
print m.group(1)
这将打印b,因为m.group(1) 捕获第一个括号的内容(group(0) 捕获整个命中,这里是abc)。
现在,考虑这个正则表达式:
a(?:.)c
这里没有捕获——这就是?:在左括号后的意思。也就是下面的代码会失败:
print m.group(1)
因为没有第一组!
【讨论】:
? = 零或一
您使用 (?:) 进行分组,而无需像使用 () 一样将组保存在临时变量中
【讨论】:
? 不是“零或多”的意思,而是“零或一”的意思。
【讨论】: