【问题标题】:Regex.Split() strange behaviourRegex.Split() 奇怪的行为
【发布时间】:2012-01-17 23:34:24
【问题描述】:

我尝试following regex 将数据拆分到文本文件中,但在测试过程中发现了一个奇怪的错误——非常简单的文件被吐出明显不正确。示例代码来说明这种行为:

        const string line = "511525,3122,9,39,2007,9,39,3127,9,39,\" -49,368.11 \",\"-32,724.16\",2,1,\" 2,347.91 \", -   ,\" 2,234.17 \", -   ,2.2,1.143,2,1.24,FALSE,1,2,0,311,511625";
        const string pattern = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)";

        Console.WriteLine();
        Console.WriteLine("SPLIT");
        var splitted = Regex.Split(line, pattern, RegexOptions.Compiled);
        foreach (var s in splitted)
        {
            Console.WriteLine(s);
        }

        Console.WriteLine();
        Console.WriteLine("REPLACE");
        var replaced = Regex.Replace(line, pattern, "!" , RegexOptions.Compiled);
        Console.WriteLine(replaced);

        Console.WriteLine();
        Console.WriteLine("MATCH");
        var matches = Regex.Matches(line, pattern);
        foreach (Match match in matches)
        {
            Console.WriteLine(match.Index);
        }

所以,如您所见,split 是唯一产生意外结果的方法(它在无效位置上分裂!)!MatchesReplace 都给出绝对正确的结果。我什至尝试在 RegexBuddy 中测试提到的正则表达式,它显示与 Regex.Matches 相同的匹配项! 我是否遗漏了什么或者它看起来像 Split 方法中的错误?

控制台输出

SPLIT
511525
, -   ," 2,234.17 "
3122
, -   ," 2,234.17 "
9
, -   ," 2,234.17 "
39
, -   ," 2,234.17 "
2007
, -   ," 2,234.17 "
9
, -   ," 2,234.17 "
39
, -   ," 2,234.17 "
3127
, -   ," 2,234.17 "
9
, -   ," 2,234.17 "
39
, -   ," 2,234.17 "
" -49,368.11 "
, -   ," 2,234.17 "
"-32,724.16"
, -   ," 2,234.17 "
2
, -   ," 2,234.17 "
1
, -   ," 2,234.17 "
" 2,347.91 "
 -   ," 2,234.17 "
 -
" 2,234.17 "
" 2,234.17 "
 -
2.2
1.143
2
1.24
FALSE
1
2
0
311
511625

REPLACE
511525!3122!9!39!2007!9!39!3127!9!39!" -49,368.11 "!"-32,724.16"!2!1!" 2,347.91 "! -   !" 2,234.17 "! -   !2.2!1.143!2!1.24!FALSE!1!2!0!311!511625

MATCH
6
11
13
16
21
23
26
31
33
36
51
64
66
68
81
87
100
106
110
116
118
123
129
131
133
135
139

【问题讨论】:

  • 我会尝试包括它们..它们很大
  • 我认为您的模式是错误的(不要问我如何正确处理),因为您的代码似乎跳过了字符串的一部分然后拆分。您的替换和匹配方法也是如此,但这些是不可见的(替换代码时可能会跳过您的字符串替换内容,但输出很好)
  • 您是否阅读过 documentation 中讨论捕获括号的评论 - 尤其是存在多个捕获括号的行为?
  • @Marnix van Valen 正如我所提到的,我已经用 RegexBuddy 检查了正则表达式。
  • @Damien_The_Unbeliever 谢谢,我会看评论

标签: c# .net regex


【解决方案1】:

根据您来自 Microsoft 的回复(添加 ExplicitCapture),问题似乎出在捕获组上。 ExplicitCapture 选项会将捕获组变成非捕获组

您可以在不使用该选项的情况下通过使组显式非捕获来执行相同操作:

const string pattern = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)";

使用 LINQPad 进行测试,似乎产生了正在寻找的结果。

docs for Regex.Split 中所述,是否有任何捕获组会有所不同

如果在 Regex.Split 表达式中使用捕获括号,则任何 捕获的文本包含在结果字符串数组中。例如, 在捕获中的连字符上拆分字符串“plum-pear” 括号将包含连字符的字符串元素添加到 返回数组。

【讨论】:

    【解决方案2】:

    Solution from MS

    (添加 ExplicitCapture 正则表达式选项)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 2015-07-20
      • 2010-10-03
      • 2021-07-12
      • 2013-10-04
      相关资源
      最近更新 更多