为什么我的RegEx得到两个不同的结果取决于平台
本文关键字:两个 结果 平台 取决于 RegEx 我的 为什么 | 更新日期: 2023-09-27 18:10:18
我有一个RegEx模式:
@"((?(?!'.'d)'D)*)('d*'.'d+|'d+)*((?(?<='d).*))"
用于将字符串分成3部分。如果有字符串
"asdf1234asdf"
"asdf .1234asdf"
"asdf. .1234asdf"
"asdf 12.34asdf"
"asdf123.4 asdf"
"asdf.1234asdf"
我需要:
1. "asdf" 2. "1234" 3. "asdf"
1. "asdf " 2. ".1234" 3. "asdf"
1. "asdf. " 2. ".1234" 3. "asdf"
1. "asdf " 2. "12.34" 3. "asdf"
1. "asdf" 2. "123.4" 3. " asdf"
1. "asdf" 2. ".1234" 3. "asdf"
但是根据我使用的平台不同,结果也不同。
Regex101.com给了我需要的结果
虽然在Regexstorm.com中,我必须将Regex中的if语句修改为非捕获组以使其工作
。:我需要从
@"((?(?!'.'d)'D)*)('d*'.'d+|'d+)*((?(?<='d).*))"
@"((?:(?!'.'d)'D)*)('d*'.'d+|'d+)*((?(?<='d).*))"
使其在.NET
那么为什么我需要摆脱'if'块?.NET
不支持if块吗?
RegEx更像英语而不是c#。它是一种用来定义模式的语言,可以在字符串中找到匹配。每种语言都需要实现自己的正则表达式引擎,因此大多数语言之间存在差异,但概念基本相同。通常,表达式越复杂,就越有可能不兼容跨平台。这就是为什么当被问及一个模糊的RegEx问题时,每个人都会问SO用户他们使用哪种编程语言。
这就是为什么像RegEx101这样的工具需要有多种"口味"来彻底测试表达式。您还会注意到"快速参考"内容(包含令牌,量词等的备忘单)随着引擎的变化而变化。
Wikipedia: 正则表达式引擎的比较。
显然,Dot-Net没有正确地执行断言条件。
我不会在任何情况下使用这种条件句。
Dot-Net在表达式条件方面做得很好。您所要做的就是将任何一组结构包装在条件组中。
示例:(?( expressional construct ) .. | ..)
所以,把断言放在里面就可以了。
注意,Dot-Net是唯一支持expressional
条件的引擎。
这可能是他们唯一正确使用的条件句。
格式:
# @"((?((?!'.'d))'D)*)('d*'.'d+|'d+)((?((?<='d)).*))"
( # (1 start)
(?(
(?! '. 'd )
)
'D
)*
) # (1 end)
( 'd* '. 'd+ | 'd+ ) # (2)
( # (3 start)
(?(
(?<= 'd )
)
.*
)
) # (3 end)
c#: string [] sAAA = {
"asdf1234asdf",
"asdf .1234asdf",
"asdf. .1234asdf",
"asdf 12.34asdf",
"asdf123.4 asdf",
"asdf.1234asdf",
};
Regex RxAAA = new Regex(@"((?((?!'.'d))'D)*)('d*'.'d+|'d+)((?((?<='d)).*))");
for (int i = 0; i < sAAA.Length; i++)
{
Match _mAAA = RxAAA.Match( sAAA[i] );
if (_mAAA.Success)
{
Console.WriteLine("1. = '"{0}'", 't2. = '"{1}'", 't3. = '"{2}'"",
_mAAA.Groups[1].Value, _mAAA.Groups[2].Value, _mAAA.Groups[3].Value );
}
}
输出:1. = "asdf", 2. = "1234", 3. = "asdf"
1. = "asdf ", 2. = ".1234", 3. = "asdf"
1. = "asdf. ", 2. = ".1234", 3. = "asdf"
1. = "asdf ", 2. = "12.34", 3. = "asdf"
1. = "asdf", 2. = "123.4", 3. = " asdf"
1. = "asdf", 2. = ".1234", 3. = "asdf"