为什么我的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得到两个不同的结果取决于平台

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"