正则表达式中 '.','?' 和 '*' 之间的区别?

正则表达式中 '.','?' 和 '*' 之间的区别?

我能否举个例子来说明这三个元素(这些被称为元字符吗?)有何不同?

我知道这*意味着全有或全无,但我不确定这是否是正确的思考方式。另一方面.?看起来一样。它们匹配一个字符,对吗?

答案1

你可能会困惑常用表达外壳全局变量

在正则表达式语法中.表示任何单个字符(通常不包括换行符),*量词表示零个或多个前一个正则表达式原子(字符或组)。?是一个量词,表示零个或前一个原子的实例,或(在支持它的正则表达式变体中)修饰符将量词行为设置为非贪婪。

在 shell globs 中,?表示单个字符(类似正则表达式的.),而*表示零个或多个字符的序列(等同于正则表达式.*)。

你可能会发现以下两个参考资料很有用:http://www.regular-expressions.info/quickstart.htmlhttp://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']

'?'匹配/验证零次或一次出现的其之前的组

检查手机号码示例。

同样如此'*'。它将检查零次或多次出现在其之前的组

组合:

'.*':接受尽可能多的可用序列。贪婪方法

'.*?' 接受第一个匹配的序列并停止。非贪婪方法

欲了解更多信息,请阅读以下两个问题...

相关内容