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和其他一些,但没有结果.
任何帮助或提示都非常感谢.谢谢
根据评论,显然原来的问题具有误导性.问题源于以下方面:
原始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)