我正在阅读 regular expressions reference我在想?和 ??人物。您能用一些例子解释一下它们的用处吗?我对它们的理解还不够。
谢谢
最佳答案
这是一个很好的问题,我花了一段时间才明白惰性 ??
量词的意义。
? - 可选(贪婪)量词
?
的用处很容易理解。如果您想同时查找 http
和 https
,您可以使用如下模式:
https?
此模式将匹配两个输入,因为它使 s
成为可选。
?? - 可选(惰性)量词
??
更微妙。它通常会执行与 ?
相同的操作。当您询问:“此输入是否满足此正则表达式?”时,它不会更改真/假结果;相反,它与问题相关:“此输入的哪一部分与此正则表达式匹配,以及哪些部分属于哪些组?” 如果输入可以通过多种方式满足模式,引擎将决定如何根据 ?
与 对其进行分组??
(或 *
与 *?
,或 +
与 +?
)。
假设您有一组想要验证和解析的输入。这是一个(诚然愚蠢的)示例:
Input:
http123
https456
httpsomething
Expected result:
Pass/Fail Group 1 Group 2
Pass http 123
Pass https 456
Pass http something
你首先想到的是this:
^(http)([a-z\d]+)$
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass http s456 No
Pass http something Yes
它们都通过了,但您不能使用第二组结果,因为您只需要第 2 组中的 456
。
好吧,我们来 try again 吧。假设第 2 组可以是字母或数字,但不能同时是两者:
(https?)([a-z]+|\d+)
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass https 456 Yes
Pass https omething No
现在第二个输入没问题,但第三个输入分组错误,因为 ?
默认是贪婪的(+
也是如此,但是 ?
首先出现)。在确定 s
是 https?
还是 [a-z]+|\d+
的一部分时,如果结果是通过这样,正则表达式引擎将始终选择左侧的那个。因此,第 2 组输掉了 s
,因为第 1 组吸收了它。
要解决这个问题,您可以创建 one tiny change :
(https??)([a-z]+|\d+)$
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass https 456 Yes
Pass http something Yes
本质上,这意味着:“如果必须的话,匹配 https
,但看看当第 1 组只是 http
时,这是否仍然可以通过。”> 引擎意识到s
可以作为[a-z]+|\d+
的一部分工作,因此它更愿意将其放入组2。
关于regex - 正则表达式中的问号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5583579/