这不是随机的。这归结为正则表达式引擎如何解释量词和潜在的回溯。通过量词,我指的是(REF)? 中的?。 According to MSDN:
通常,量词是贪婪的;它们导致正则表达式
引擎匹配尽可能多的特定模式的出现
可能的。附加 ?量词的字符使它变得懒惰;它
导致正则表达式引擎匹配的出现次数尽可能少
可能。
换句话说,? 是贪婪的,?? 是懒惰的。两者都匹配零次或一次,但它们会影响匹配的执行方式。
关于回溯,MSDN mentions:
正则表达式引擎尝试完全匹配可选或
替代子表达式。当它前进到下一种语言时
子表达式中的元素并且匹配不成功,则
正则表达式引擎可以放弃其成功的一部分
匹配并返回到先前保存的状态以进行匹配
正则表达式作为一个整体与输入字符串。这个流程
返回到先前保存的状态以查找匹配项称为
回溯。
另一个有用的资源可以在这里找到更多关于回溯的信息:Possessive Quantifiers。
要直接回答您的问题,我们可以比较这两种方法。
贪婪的方法
原始输入: REFmisc03-123456789012-213
使用(REF)? 会将您的文本与 4 个组匹配(不包括整个匹配的第一个组),并且所有组都将成功匹配:
- 参考
- misc03
- 123456789012
- 213
这符合您的第一个可能的匹配场景(定义松散):
(REF)(misc03)-(123456789012)-(213)
只要"misc..." 部分的长度为 1-10 个字符,匹配将是相同的,所有 1-10 个字符都出现在第二组中。 REF 部分将始终在第一组中匹配。
新输入: REF-123456789012-213
"misc..." 部分不存在。由于(REF)? 是可选的,而(.{1,10}) 不是,正则表达式引擎将使用"REF" 输入来满足模式的后者(必需)部分并忽略前者(可选)部分。这将产生以下组值:
-
""(空字符串,Success 属性 = false)
- 参考
- 123456789012
- 213
懒惰的方法
原始输入: REFmisc03-123456789012-213
通过使用(REF)??,并保持模式的其余部分相同,量词变得惰性,这将返回具有这些值的 4 个组:
-
""(空字符串,Success 属性 = false)
- REFmisc03
- 123456789012
- 213
这符合您的第二个可能的匹配场景:
()(REFmisc03)-(123456789012)-(213)
由于第一组是可选的,带有惰性量词,因此正则表达式引擎可以忽略它。由于 "REFmisc03" 的长度为 9 个字符,因此引擎会将 "REF" 与 "misc03" 混为一谈,因为它们适合 (.{1,10}) 组。
新输入: REF-123456789012-213
这与贪婪模式的行为相似,并且适用相同的推理。
另一个新的输入: REFmisc0345-123456789012-213
在此示例中,"misc0345" 部分的长度为 8 个字符。尽管该模式使用了惰性量词,但它无法将 "REFmisc0345" 放入第二组,因为它超过了 10 个字符的限制。正则表达式引擎将回溯并匹配第一组中的"REF",以及第二组中的"misc0345":
- 参考
- misc0345
- 123456789012
- 213