![正则表达式中 '.','?' 和 '*' 之间的区别?](https://linux22.com/image/886414/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%B8%AD%20'.'%EF%BC%8C'%EF%BC%9F'%20%E5%92%8C%20'*'%20%E4%B9%8B%E9%97%B4%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9F.png)
我能否举个例子来说明这三个元素(这些被称为元字符吗?)有何不同?
我知道这*
意味着全有或全无,但我不确定这是否是正确的思考方式。另一方面.
和?
看起来一样。它们匹配一个字符,对吗?
答案1
你可能会困惑常用表达和外壳全局变量
在正则表达式语法中.
表示任何单个字符(通常不包括换行符),*
而量词表示零个或多个前一个正则表达式原子(字符或组)。?
是一个量词,表示零个或一前一个原子的实例,或(在支持它的正则表达式变体中)修饰符将量词行为设置为非贪婪。
在 shell globs 中,?
表示单个字符(类似正则表达式的.
),而*
表示零个或多个字符的序列(等同于正则表达式.*
)。
你可能会发现以下两个参考资料很有用:http://www.regular-expressions.info/quickstart.html和http://mywiki.wooledge.org/glob
答案2
直接取自维基百科:
? 问号表示前一个元素出现零次或一次。例如,colou?r 匹配“color”和“colour”。
*星号表示前一个元素出现零次或多次。例如,ab*c 可匹配“ac”、“abc”、“abbc”、“abbbc”等等。
最大的区别是星号匹配零个或多个出现,而问号匹配零个或一个发生。比较以下两个例子:
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'
colour
color
colouur
因为colouur
字母 u (限定符 之前的前一个元素?
)出现了多次,所以它与 不匹配?
,但与 匹配*
类似例子:
$ printf "error\neror\ner\n" | egrep 'er?or'
eror
$ printf "error\neror\ner\n" | egrep 'er*or'
error
eror
来自同一维基百科页面:
匹配任意单个字符(许多应用程序不包括换行符,具体哪些字符被视为换行符取决于具体类型、字符编码和平台,但可以安全地假设换行符包含在内)。在 POSIX 括号表达式中,点字符匹配文字点。例如,ac 匹配“abc”等,但 [ac] 仅匹配“a”、“.”或“c”。
在我们的例子中,
$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'
colouur
最后一句恰如其分地写成match any line that has "colou", plus any character, plus letter "r"
结论
您曾问过:“我知道 '*' 表示全有或全无,但我不确定这是否是正确的思考方式。另一方面,'.' 和 '?' 似乎相同。”如您所见,点和星号并不完全相同。点作用于可能占据该特定位置的任何字符,而问号作用于前一个元素。
答案3
注意:Examples provided are in Python.
尽管概念保持不变。
'.'
是匹配符号匹配除以下字符之外的任何字符换行符(在 Python 中,这也可以用re.DOTALL
参数覆盖)。因此,它也被称为通配符。
'*'
是量词(定义元素出现的频率)。是{0,}。
它的意思是“匹配零个或多个”— 星号前面的组可以在文本中出现任意次数。它可以完全不存在,也可以反复重复。
'?'
也量词. 是{0,1}。
它的意思是“匹配该问号前的组中的零个或一个。”也可以解释为问号前面的部分是可选的。
例如:
pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'
mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'
在上面的例子中,“?”表示其前面的两位数字是可选的。它们可以不出现,或者最多出现一次。
“.”和“?”之间的区别:
'.'
匹配/接受/验证任意单个字符它在正则表达式中所占的位置。
例如:
pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']
'?'
匹配/验证零次或一次出现的其之前的组。
检查手机号码示例。
同样如此'*'
。它将检查零次或多次出现在其之前的组。
组合:
'.*'
:接受尽可能多的可用序列。贪婪方法。
'.*?
' 接受第一个匹配的序列并停止。非贪婪方法
欲了解更多信息,请阅读以下两个问题...