* 和 ** 的区别

4
"*"和"**"有什么区别?为什么在使用"pattern.compile(".**");"时".**"不能编译通过?"

3
对于“.**”,你认为第二个“*”应该被应用于什么? - azurefrog
1
你想要它匹配什么? - Lucas Araujo
@lbarros 只是一个字符串。不是文件路径。 - Squeez
@azurefrog 嗯...我对于字符串匹配中的 *** 有些困惑。所以我在这里问一下。 - Squeez
4个回答

2

在评估正则表达式时,*是一个元字符,表示前面的字符出现0次或多次。

当你写.**时,它会分解为.*(表示0个或多个任意字符)后跟*,其中没有前导字符,因此该模式无法编译。


2

. 表示“(几乎)任何字符”。

* 表示“匹配前一个字符0次或多次”。

第二个 * 在此上下文中没有任何意义。


我很好奇,“.”不能匹配什么?我一直以为它可以匹配任何字符。 - Bethany Louise
@BethanyLouise,默认情况下它不匹配换行符。 - shmosel
“第二个*在这个上下文中没有意义”这句话并不正确。它仍然是一个量词,但是放错位置会导致异常。 - Wiktor Stribiżew

2
请参阅Java“量词”参考文档:Quantifiers
Greedy  Reluctant   Possessive  Meaning
X?      X??         X?+         X, once or not at all
X*      X*?         X*+         X, zero or more times
X+      X+?         X++         X, one or more times
X{n}    X{n}?       X{n}+       X, exactly n times
X{n,}   X{n,}?      X{n,}+      X, at least n times
X{n,m}  X{n,m}?     X{n,m}+     X, at least n but not more than m times
没有**量词。当您在+之后使用+*?(甚至{n,m})时,可以创建一个占有量词(请参见上表),但在*之后添加*量词被认为是用户错误

这就是为什么.*会匹配除换行符之外的0个或多个字符(没有Pattern.DOTALL修饰符),而.**会抛出异常的原因。

请注意,在线正则表达式测试器也会警告您此问题:Dangling meta character '*' near index 2 .** ^(同样的警告也出现在OCPSoft正则表达式测试器中)。


好的,我明白了。但是我仍然不理解以下内容:当用户搜索时,例如按文章ID搜索,并且他想检索所有文章时,他可以通过***请求。这两者之间有什么区别? - Squeez
1
什么意思?如果您需要使用正则表达式匹配任何字符串,甚至是空字符串,您需要使用(?s)^.*$。如果您允许使用*来检索某些内容,则它不再是正则表达式,而是一个通配符。 - Wiktor Stribiżew
哦,通配符,谢谢。*** 有什么区别? - Squeez
1
如果它是通配符?那么 ** 的意思是 获取所有内容,然后获取剩下的所有内容。这没有多少意义,对吧?第二个 * 不匹配任何东西。但这是模式匹配,不是基于正则表达式的。 - Wiktor Stribiżew
1
如果 * 是通配符,它将匹配任何字符串中的0个或多个字符。当您请求所有内容时,您仍然只会得到所有内容,而不是所有内容的两倍,对吧? :) - Wiktor Stribiżew
显示剩余2条评论

1

* 在正则表达式中是一个量词,如果您想使用它而不带任何特殊意义,请转义它 \*

.* - 将匹配任何单个字符,但不是换行符(换行、回车、下一行、行分隔符、段落分隔符) .* 出现零次或多次,尽可能多地匹配,必要时回溯(贪婪模式* 您的正则表达式可能会找到零长度匹配。Java 8允许在先前匹配结束的位置上进行零长度匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接