我有一个非常古老(并且奇怪分隔)的字符串代表一个表格,我希望在两个“标签”之间得到所有文本(它们是令人厌恶的......在这里,它们充满了他们的荣耀):< / p>
<<<NAME=Test User>>>
<<<DATE=11/06/2014>>>
|||COMMENTS_FOLLOW_UP=\\myserver\Reporter\testu\20140611.rtf|||
|||COMMENTS_APPOINTMENT_LIST=\\myserver\Reporter\testu\COMMENTS_APPOINTMENT_LIST_20140611.rtf|||
~~~ START MONTHLY BREAKDOWN ~~~
### ROW START ###
<<<ACTIVITY=Target Group Support>>>
<<<PERCENTAGE_OF_TIME_TAKEN_FOR_THE_MONTH=25%>>>
### ROW END ###
### ROW START ###
<<<ACTIVITY=Non-target Group Support>>>
<<<PERCENTAGE_OF_TIME_TAKEN_FOR_THE_MONTH=25%>>>
### ROW END ###
### ROW START ###
<<<ACTIVITY=Networking/Guest Speaking Activities>>>
<<<PERCENTAGE_OF_TIME_TAKEN_FOR_THE_MONTH=25%>>>
### ROW END ###
### ROW START ###
<<<ACTIVITY=Processing initial calls, making appointments, completing reports and other tasks>>>
<<<PERCENTAGE_OF_TIME_TAKEN_FOR_THE_MONTH=25%>>>
### ROW END ###
### ROW START ###
<<<ACTIVITY=Total>>>
<<<PERCENTAGE_OF_TIME_TAKEN_FOR_THE_MONTH=100%>>>
### ROW END ###
~~~ END MONTHLY BREAKDOWN ~~~
~~~ START EVENTS ~~~
### ROW START ###
<<<DATE=11/06/2014 12:00:00 AM>>>
<<<EVENT_NAME=Test's Event>>>
<<<NAME_OF_ORGANISATION/GROUP=Tests Org>>>
<<<PARTICIPANT_GROUP=Test>>>
<<<NUMBER_OF_PARTICIPANTS=50>>>
### ROW END ###
~~~ END EVENTS ~~~
所以我需要在分隔符~~~ START XXX ~~~
和~~~ END XXX ~~~
所以这就是我掀起的模式:~~~ START .+~~~(.*)~~~ END .+~~~
;
正如你所看到的,正是一个正则表达的主人,我不是。
注意:我正在使用SingleLine
标志。
问题:这与正确的文字匹配,但只返回一个组,即第一个表标记的正文文本组。如何让C#regex-a-tron 9000从第二个匹配组中的 second 标签返回正文文本?
答案 0 :(得分:3)
您可以使用Regex.Matches:
var matches = Regex.Matches(input_string, regex);
foreach (var m in matches)
{
// do whatever
}
或者,你可以获得一场比赛,然后获得下一场比赛等等:
var m = Regex.Match(input_string, regex);
while (m.Success)
{
// do something with this match
// then get the next match
m = m.NextMatch();
}
答案 1 :(得分:2)
首先,我建议您将正则表达式更改为:
(?s)~~~ START ([^~]*).*?END \1 ~~~
START
之后,([^~]*)
会抓住该块的标题。这样可以确保我们可以确保END
稍后匹配。.*?
最多匹配...... \
反向引用)和关闭波浪号。示例代码
这是一个完整的程序,您可以使用它进行测试。我没试过。你需要在那里粘贴字符串。
using System;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
class Program {
static void Main() {
string s1 = @"PASTE YOUR STRING HERE";
var myRegex = new Regex(@"(?s)~~~ START ([^~]*).*?END \1 ~~~");
MatchCollection AllMatches = myRegex.Matches(s1);
Console.WriteLine("\n" + "*** Matches ***");
if (AllMatches.Count > 0) {
foreach (Match SomeMatch in AllMatches) {
Console.WriteLine("Title: " + SomeMatch.Groups[1].Value);
Console.WriteLine("Overall Match: " + SomeMatch.Value);
}
}
Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();
} // END Main
} // END Program
答案 2 :(得分:1)
你需要在一个循环中多次调用正则表达式匹配器,直到没有匹配。考虑修改表达式以避免回溯 - 在您的情况下,这是非常可能的,因为.+
是贪婪的(而不是“不情愿”)。
这是一个如何做到的小演示:
var regex = new Regex("~~~ START ([^~]+)~~~([^~]*)~~~ END ([^~]+)~~~", RegexOptions.Multiline);
var m = regex.Match(Data);
while (m.Success) {
Console.WriteLine("------ Start: {0} --------", m.Groups[1]);
Console.WriteLine(m.Groups[2]);
Console.WriteLine("------ End: {0} --------", m.Groups[3]);
m = m.NextMatch();
}
This example running on ideone.
请注意上述更改 - 我将.
替换为[^~]
以匹配第一个波浪形,并且还捕获了用于打印的开始和结束标记的内容。