正则表达式在C#中拆分多行文本

时间:2016-06-16 14:04:30

标签: c# regex multiline

我正在尝试构建一个正则表达式来拆分WhatsApp通过电子邮件发送的邮件存档。

示例:

23.02.16, 11:01 - Herr Paul Muster: han vpn verbindig zu ufgmacht und die kappt ja sinternet
23.02.16, 11:01 - Herr Paul Muster: jetzt channi mi nümme verbinde 
23.02.16, 11:10 - Herr Paul Muster: merci
25.02.16, 09:09 - Herr Peter Nachname: Bin i 15min im office
07.03.16, 09:29 - Herr Peter Nachname: Da ich weiss dases eh nid kommuniziert wird, schribis eu au. Ich wird hüt dihei blibe, han migräneartigi grindschmerze...lg
07.03.16, 09:30 - Markus: Ok, danke für d'info (und dini hellseherische fähigkeite)
Gueti besserig
04.04.16, 09:24 - Herr Peter Nachname: Bi grad im office 
13.04.16, 19:00 - Herr Paul Muster: mir sind usem büro usgschlosse 
13.04.16, 19:00 - Herr Paul Muster: händ meeting gah 
und all händ dä schlüssel 
im büro 
13.04.16, 19:08 - Herr Peter Nachname: Lol 
13.04.16, 19:12 - Herr Paul Muster: du bisch eh grossi hilf  bisch nid per zuefall ih dä nöchi?

每行末尾都是一个换行符(\ n)。 目前我正在使用以下代码:

new Regex(@"([\d]{2}.[\d]{2}.[\d]{2}, [\d]{2}:[\d]{2})[\s]-[\s](.*):[\s](.*)");

MatchCollection的第一组包含日期,第二部分包含发件人。 第三组仅包含消息文本,直到行尾。 但我希望得到整个信息,包括换行符或其他任何内容,直到datepart的下一场比赛。

我查了几个论坛和QA页面,但我无法找到解决问题的方法。所以也许这里有人可以给我一个正确的解决方案来解决我的问题。

4 个答案:

答案 0 :(得分:0)

您可以在第一个Regex.Replace():

中使用此解决方法
string pattern =  @"(.)$\n(\D\D[^.]\D\D[^.]\D\D)";
string input = ""; // Your multiline input
string replacement = "$1$2";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);

哪个会给你:

23.02.16, 11:01 - Herr Paul Muster: han vpn verbindig zu ufgmacht und die kappt ja sinternet
23.02.16, 11:01 - Herr Paul Muster: jetzt channi mi nümme verbinde 
23.02.16, 11:10 - Herr Paul Muster: merci
25.02.16, 09:09 - Herr Peter Nachname: Bin i 15min im office 07.03.16, 09:29 - Herr Peter Nachname: Da ich weiss dases eh nid kommuniziert wird, schribis eu au. Ich wird hüt dihei blibe, han migräneartigi grindschmerze...lg 07.03.16, 09:30 - Markus: Ok, danke für d'info (und dini hellseherische fähigkeite)Gueti besserig
04.04.16, 09:24 - Herr Peter Nachname: Bi grad im office 
13.04.16, 19:00 - Herr Paul Muster: mir sind usem büro usgschlosse  13.04.16, 19:00 - Herr Paul Muster: händ meeting gah und all händ dä schlüssel im büro 
13.04.16, 19:08 - Herr Peter Nachname: Lol 
13.04.16, 19:12 - Herr Paul Muster: du bisch eh grossi hilf  bisch nid per zuefall ih dä nöchi?

然后,您可以应用正则表达式new Regex(@"([\d]{2}.[\d]{2}.[\d]{2}, [\d]{2}:[\d]{2})[\s]-[\s](.*):[\s](.*)");来建立您的论坛。

限制:

如果您的新行以日期开头但不是新条目,则无效。

答案 1 :(得分:0)

试试这个

string pattern = @"([\d]{2}.[\d]{2}.[\d]{2}, [\d]{2}:[\d]{2})[\s]-[\s](.*?):[\s](.*?)(?=\r\n\d|\z)";

var regex = new Regex(pattern, RegexOptions.Singleline);

注意一些懒惰的量词。

最后,我们检查下一句话开头或文件末尾的数字是否存在。

单线选项需要指向捕获的任何角色,包括换行符。

答案 2 :(得分:0)

感谢所有输入

我能够使用以下正则表达式模式从Sebasian Proske的输入中解决我的问题:

new Regex(@"(\d{2}\.\d{2}\.\d{2}, \d{2}:\d{2})\s-\s(.*?):\s((?:.+|\n(?!\d{2}\.\d{2}\.\d{2}, \d{2}:\d{2}))+)");

答案 3 :(得分:0)

这是一个仅支持.NET的解决方案:

new Regex(@"(^\d{2}\.\d{2}\.\d{2}, \d{2}:\d{2})\s-\s([^:]*):\s(.*?)$",
    RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.RightToLeft);

Multiline选项允许^$在行边界匹配,Singleline允许.匹配换行符,RightToLeft导致匹配从字符串末尾开始向后移动。

非贪婪(.*?)导致它在Date, Time - Name:序列的第一次出现(或下一次出现,后退)时停止匹配,因此它一次只匹配一行。比赛将按相反的顺序进行,但这些比赛将赢得比赛。

如果感觉太像黑魔法,你可以改用它:

new Regex(@"(^\d{2}\.\d{2}\.\d{2}, \d{2}:\d{2})\s-\s([^:]*):\s((?:(?!^\d{2}\.\d{2}\.\d{2},).)*)$",
    RegexOptions.Multiline | RegexOptions.Singleline);

(?:(?!^\d{2}\.\d{2}\.\d{2},).)*匹配零个或多个字符(包括换行符,因为Singleline选项),直到下一个字符是一行开头的日期开头(或直到没有更多字符)。