正则表达式预测在.NET中不起作用

And*_*eas 2 .net c# regex regex-lookarounds

我有一个与Regexr.com一起使用的前瞻性Regex,但在.NET应用程序中使用它时却没有.

这是一些示例输入数据(请注意,我只是为了可读性而创建了行中断,文本实际上只是一个长行,因此需要一个正则表达式).

26. AUG\r\n2014\r\n27.08 Testing 1\r\n -100\r\n
20. AUG\r\n2014\r\n27.08 Testing 2\r\n -90\r\n
15. AUG\r\n2014\r\n27.08 Testing 3\r\n 200\r\n
9. AUG\r\n2014\r\n27.08 Testing 4\r\n 50\r\n
4. AUG\r\n2014\r\n27.08 Testing 5\r\n -200\r\n
25. JUL\r\n2014\r\n27.08 Testing 5\r\n -200\r\n
Run Code Online (Sandbox Code Playgroud)

使用以下正则表达式:

(.+?)(?=(\\r\\n\d{1,2}[.] [A-Z]{3})|$)
Run Code Online (Sandbox Code Playgroud)

,我希望捕获每一行,想要用"20. AUG"分隔它们等等.由于也应该捕获分隔符,我使用前瞻.Regexr.com上的一切都很棒,例如:http://regexr.com/39fd7

在.NET中执行此操作时:

Regex.Matches(input, "(.+?)(?=(\r\n\\d{1,2}[.] [A-Z]{3})|$)")
Run Code Online (Sandbox Code Playgroud)

我只得到这些结果:

-100
-90
200
50
-200
-200
Run Code Online (Sandbox Code Playgroud)

我尝试过各种RegexOptions,比如multiline和其他一些,但没有结果.

任何帮助或提示都非常感谢.谢谢

Sam*_*ell 5

编辑

根据评论,显然原来的问题具有误导性.问题源于以下方面:

原始C#代码使用包含确切字符序列的字符串文字\r\n,如下所示:

string input = "Example\r\nText";
Run Code Online (Sandbox Code Playgroud)

然后将字符串的内容不加改变地复制到在线正则表达式测试器中,因此测试运行在以下等效项上:

string notActuallyTheInput = "Example\\r\\nText"; 
Run Code Online (Sandbox Code Playgroud)

现在很清楚,问题意味着input字符串文字写在一行上,但输入本身确实跨越多行.因此,问题(.+?)出在表达的部分.正如Robin所提到的,.默认情况下该字符与换行符不匹配.所需的行为是该RegexOptions.Singleline选项的行为,如以下示例程序所示.

using System;
using System.Text.RegularExpressions;

class Program
{
    private const string Input =
        "26. AUG\r\n2014\r\n27.08 Testing 1\r\n -100\r\n" +
        "20. AUG\r\n2014\r\n27.08 Testing 2\r\n -90\r\n" +
        "15. AUG\r\n2014\r\n27.08 Testing 3\r\n 200\r\n" +
        "9. AUG\r\n2014\r\n27.08 Testing 4\r\n 50\r\n" +
        "4. AUG\r\n2014\r\n27.08 Testing 5\r\n -200\r\n" +
        "25. JUL\r\n2014\r\n27.08 Testing 5\r\n -200\r\n";

    static void Main(string[] args)
    {
        string pattern = @"(.+?)(?=(\r\n\d{1,2}[.] [A-Z]{3})|$)";
        var matches = Regex.Matches(Input, pattern, RegexOptions.Singleline);

        Console.WriteLine("{0} Matches:", matches.Count);
        foreach (Match match in matches)
            Console.WriteLine("  {0}", match.Value.Replace("\r", "\\r").Replace("\n", "\\n"));

        // OUTPUT:
        //
        // 7 Matches:
        //   26. AUG\r\n2014\r\n27.08 Testing 1\r\n -100
        //   \r\n20. AUG\r\n2014\r\n27.08 Testing 2\r\n -90
        //   \r\n15. AUG\r\n2014\r\n27.08 Testing 3\r\n 200
        //   \r\n9. AUG\r\n2014\r\n27.08 Testing 4\r\n 50
        //   \r\n4. AUG\r\n2014\r\n27.08 Testing 5\r\n -200
        //   \r\n25. JUL\r\n2014\r\n27.08 Testing 5\r\n -200\r
        //   \n
    }
}
Run Code Online (Sandbox Code Playgroud)

原始答案

问题可能源于将正则表达式错误地转换为C#字符串文字.

以下表达式:

(.+?)(?=(\\r\\n\d{1,2}[.] [A-Z]{3})|$)
Run Code Online (Sandbox Code Playgroud)

将在C#字符串文字中写为以下任一项:

"(.+?)(?=(\\\\r\\\\n\\d{1,2}[.] [A-Z]{3})|$)"

@"(.+?)(?=(\\r\\n\d{1,2}[.] [A-Z]{3})|$)"
Run Code Online (Sandbox Code Playgroud)

由于输入不包含任何引号字符,后者肯定是最简单的翻译,因为它是原始表达式的精确副本.

完成重现结果的程序

using System;
using System.Text.RegularExpressions;

class Program
{
    private const string Input =
        "26. AUG\\r\\n2014\\r\\n27.08 Testing 1\\r\\n -100\\r\\n" +
        "20. AUG\\r\\n2014\\r\\n27.08 Testing 2\\r\\n -90\\r\\n" +
        "15. AUG\\r\\n2014\\r\\n27.08 Testing 3\\r\\n 200\\r\\n" +
        "9. AUG\\r\\n2014\\r\\n27.08 Testing 4\\r\\n 50\\r\\n" +
        "4. AUG\\r\\n2014\\r\\n27.08 Testing 5\\r\\n -200\\r\\n" +
        "25. JUL\\r\\n2014\\r\\n27.08 Testing 5\\r\\n -200\\r\\n";

    static void Main(string[] args)
    {
        string pattern = @"(.+?)(?=(\\r\\n\d{1,2}[.] [A-Z]{3})|$)";
        var matches = Regex.Matches(Input, pattern);

        Console.WriteLine("{0} Matches:", matches.Count);
        foreach (Match match in matches)
            Console.WriteLine("  {0}", match.Value);

        // OUTPUT:
        //
        // 6 Matches:
        //   26. AUG\r\n2014\r\n27.08 Testing 1\r\n -100
        //   \r\n20. AUG\r\n2014\r\n27.08 Testing 2\r\n -90
        //   \r\n15. AUG\r\n2014\r\n27.08 Testing 3\r\n 200
        //   \r\n9. AUG\r\n2014\r\n27.08 Testing 4\r\n 50
        //   \r\n4. AUG\r\n2014\r\n27.08 Testing 5\r\n -200
        //   \r\n25. JUL\r\n2014\r\n27.08 Testing 5\r\n -200\r\n
    }
}
Run Code Online (Sandbox Code Playgroud)