如何选择首选(但特定)正则表达式匹配超过默认(但通用)一个
本文关键字:默认 一个 选择 何选择 正则表达式 | 更新日期: 2023-09-27 18:15:33
我试图捕获文本块的各个部分,包括它是否具有开始或结束引号,然后文本块本身,不包括那些引号。当我只有一个结束引号,句号和结束引号或者只有一个结束引号时,Regex模式工作得很好。
string test = @"""This has a begin quote, period and end quote.""" + Environment.NewLine +
@"""This has a begin quote and period." + Environment.NewLine +
@"""This has a begin quote and end quote""" + Environment.NewLine +
@"""This has a begin quote only" + Environment.NewLine;
string pattern = @"^'s*(?<BeginQuote>"")?" +
@"(?<BodyPattern>.+(('.(?=""?'s*$))|(?=""'s*$)))" +
@"(?<EndQuote>""(?='s*$))?";
Regex rx = new Regex(pattern, RegexOptions.Multiline);
MatchCollection matches = rx.Matches(test);
foreach (Match m in matches)
{
GroupCollection groups = m.Groups;
Console.WriteLine("Beginning Quotation Mark: {0}", groups["BeginQuote"].Success);
Console.WriteLine("BodyPattern: {0}", groups["BodyPattern"]);
Console.WriteLine("Ending Quotation Mark: {0}", groups["EndQuote"].Success);
}
输出如下:
起始引号:True
bodyppattern:这有一个开始引号,句号和结束引号。
结束引号:True
起始引号:True
bodyppattern:它有一个起始引号和句号。
结束引号:False
起始引号:True
bodyppattern:这有一个开始引号和结束引号
结束引号:True
问题是当我试图为既没有结束引号也没有句号的情况提供匹配时。我尝试了多种变化来捕捉字符串的结束。这总是有效的,但最终也会捕获任何结束引用。如果其他测试不起作用,我如何使此选项成为"后备"选项?
下面是我在Regex模式中尝试的一种变体:
string pattern = @"^'s*(?<BeginQuote>"")?" +
@"(?<BodyPattern>.+(('.(?=""?'s*$))|(?=""'s*$)|($)))" +
@"(?<EndQuote>""(?='s*$))?";
然而,此模式始终默认为字符串结束选项:
起始引号:True
bodyppattern:它有一个开始引号,句号和结束引号。"
结束引号:False
起始引号:True
bodyppattern:它有一个起始引号和句号。
结束引号:False
起始引号:True
bodyppattern:这有一个开始引号和结束引号"
结束引号:False
起始引号:True
bodyppattern:这个只有一个起始引号
结束引号:False
我还尝试将字符串结束选项作为第一选择(相同的输出;并试图使该表达式"懒惰"(但我使用"??"进行的几次尝试产生了相同的输出)。我还尝试了对可选方案的各种分组(虽然可能不是所有的可能性),但输出结果相同。
+
量词贪心,用+?
代替。这应该能成功。
string test = @"""This has a begin quote, period and end quote.""" + "'n" +
@"""This has a begin quote and period." + "'n" +
@"""This has a begin quote and end quote""" + "'n" +
@"""This has a begin quote only";
Regex rx = new Regex(@"(?m)^'s*(?<BeginQuote>"")?(?<BodyPattern>.+?(?:'.|(?=""|$)))(?<EndQuote>"")?");
foreach (Match m in rx.Matches(test)) {
Console.WriteLine("Beginning Quotation Mark: {0}", m.Groups["BeginQuote"].Success);
Console.WriteLine("BodyPattern: {0}", m.Groups["BodyPattern"]);
Console.WriteLine("Ending Quotation Mark: {0}", m.Groups["EndQuote"].Success);
Console.WriteLine("--------------------------");
}
输出Beginning Quotation Mark: True
BodyPattern: This has a begin quote, period and end quote.
Ending Quotation Mark: True
--------------------------
Beginning Quotation Mark: True
BodyPattern: This has a begin quote and period.
Ending Quotation Mark: False
--------------------------
Beginning Quotation Mark: True
BodyPattern: This has a begin quote and end quote
Ending Quotation Mark: True
--------------------------
Beginning Quotation Mark: True
BodyPattern: This has a begin quote only
Ending Quotation Mark: False
--------------------------
我把hwnd的答案标记为正确,因为它给了我如何使用惰性量词的线索。但是,我使用了我的代码,因为每当您向文本添加内部引号或添加额外的空白时,Regex都会失败。我修改了测试文本,使其更易于阅读。下面是我最终使用的:
string test = "'"This has a begin quote, '"period'" and end quote.'t '"'n " +
"'"This has a begin quote and period.'n" +
"This has no begin quote but an end quote'"'n" +
"'"This has a '"begin'" quote only 'n" ;
string pattern = @"^'s*(?<BeginQuote>"")?" +
@"(?<BodyPattern>.+?(('.(?=""?'s*$))|(?=""'s*$)|($)))" +
@"(?<EndQuote>""(?='s*$))?";
Regex rx = new Regex(pattern, RegexOptions.Multiline);
MatchCollection matches = rx.Matches(test);
输出:起始引号:True
bodyppattern:它有一个开始引号,"句号"和结束引号。
结束引号:True
起始引号:True
bodyppattern:它有一个起始引号和句号。
结束引号:False
起始引号:False
bodyppattern:没有开始引号,只有结束引号
结束引号:True
起始引号:True
BodyPattern:只有一个"begin"引号
结束引号:False