我正在尝试捕获文本块的各个部分,包括它是否具有开始或结束引号,然后是文本块本身(不包括那些引号)。当我只有结尾报价,句点和结尾报价或只有结尾报价时,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
BodyPattern:它具有开始报价,句号和结束报价。
结束引号:True
起始引号:True
BodyPattern:这有一个开始的报价和句点。
结尾引号:False
起始引号:True
BodyPattern:这有一个开始引号和一个结束引号
结束引号:True
问题是当我尝试为没有结尾引号或句号的情况提供匹配项时。我尝试了多种变体来捕捉字符串的结尾。这始终有效,但最终也会捕获任何结尾的引号。如果其他测试不起作用,如何使该选项成为“后备”选项?
这是我在Regex模式中尝试的一种变体:
string pattern = @"^\s*(?<BeginQuote>"")?" +
@"(?<BodyPattern>.+((\.(?=""?\s*$))|(?=""\s*$)|($)))" +
@"(?<EndQuote>""(?=\s*$))?";
但是,此模式始终默认为替代字符串的结尾:
起始引号:True
BodyPattern:它具有开始报价,句号和结束报价。”
结尾引号:False
起始引号:True
BodyPattern:这有一个开始的报价和句点。
结尾引号:False
起始引号:True
BodyPattern:这有一个开始引号和一个结束引号”
结尾引号:False
起始引号:True
BodyPattern:仅具有开始报价
结尾引号: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
--------------------------