Regex前瞻赢得';不能在.NET中工作
本文关键字:不能 NET 工作 Regex | 更新日期: 2023-09-27 18:21:09
我得到了一个带有前瞻性的Regex,它可以与Regexr.com一起使用,但在.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
使用以下正则表达式:
(.+?)(?=(''r''n'd{1,2}[.] [A-Z]{3})|$)
,我希望捕捉每一行,并希望用"20"来分隔它们。AUG"等等。由于分隔符也应该被捕获,所以我使用前瞻。Regexr.com上的一切都很好,例如:http://regexr.com/39fd7
在.NET:中执行此操作时
Regex.Matches(input, "(.+?)(?=('r'n''d{1,2}[.] [A-Z]{3})|$)")
我只得到这些结果:
-100
-90
200
50
-200
-200
我尝试过各种RegexOptions,比如multiline和其他一些,但没有结果。
如有任何帮助或提示,我们将不胜感激。感谢
编辑
根据这些评论,原来的问题显然具有误导性。问题源于以下方面:
原始的C#代码使用一个字符串文字,其中包含确切的字符序列'r'n
,例如:
string input = "Example'r'nText";
然后,字符串的内容被复制到在线正则表达式测试仪中,保持不变,因此测试在以下等价物上运行:
string notActuallyTheInput = "Example''r''nText";
现在很清楚,这个问题意味着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
}
}
原始答案
这个问题可能源于正则表达式到C#字符串文本的错误翻译。
以下表达式:
(.+?)(?=(''r''n'd{1,2}[.] [A-Z]{3})|$)
将在C#字符串文字中写成以下任意一个:
"(.+?)(?=(''''r''''n''d{1,2}[.] [A-Z]{3})|$)"
@"(.+?)(?=(''r''n'd{1,2}[.] [A-Z]{3})|$)"
由于输入不包含任何引号字符,后者肯定是最简单的翻译,因为它是原始表达式的精确副本。
复制结果的完整程序
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
}
}
如果您的文本始终具有相同的格式(由4列,由文字'r'n
分隔),则可以使用以下简单模式:
string pattern = @"(?:[^'']+''r''n){4}";
示例
.
与换行符不匹配。
您的字符串显示为"一行",但包含换行符('r'n
),一旦在字符串文字中进行解释,就会阻止点与您想要的所有内容匹配。
它将尝试匹配26. AUG
,然后匹配2014
。。。直到-100
,当前景最终匹配时,即您的最终结果。
使用点匹配所有标志:
(?s).+?(?=''r''n'd{1,2}[.] [A-Z]{3}|$)