regex - 正则表达式中的问号

标签 regex regex-greedy

我正在阅读 regular expressions reference我在想?和 ??人物。您能用一些例子解释一下它们的用处吗?我对它们的理解还不够。

谢谢

最佳答案

这是一个很好的问题,我花了一段时间才明白惰性 ?? 量词的意义。

? - 可选(贪婪)量词

? 的用处很容易理解。如果您想同时查找 httphttps,您可以使用如下模式:

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

现在第二个输入没问题,但第三个输入分组错误,因为 ? 默认是贪婪的(+ 也是如此,但是 ? 首先出现)。在确定 shttps? 还是 [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/

相关文章:

java - 将字符串拆分为句子

python - 使用 RE 扫描仪查找双引号中的 Material ?

正则表达式信用卡号测试

javascript - 用于匹配仅由字母列表构成的单词的正则表达式

ReGex,如何查找字符串的第二个实例

java - 使用 Java 中的正则表达式从字符串中删除单词的所有独立出现

正则表达式:带约束的十进制数和末尾允许的某些字母字符

regex - 查找以具有特定模式的下划线开头的单词的换行符

regex - 正则表达式,用于用新行捕获模式

regex - perl 正则表达式从字符串 : why does it work? 中删除初始全空白行