正则表达式在 C# 中拆分多行文本
Regex to split multiline text in C#
我正在尝试构建一个正则表达式来拆分从 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 页面,但找不到解决我的问题的方法。所以也许这里有人可以给我提示以解决我的问题。
您可以先将此解决方法用于 Regex.Replace():
string pattern = @"(.)$\n(\D\D[^.]\D\D[^.]\D\D)";
string input = ""; // Your multiline input
string replacement = "";
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](.*)");
来创建您的群组。
限制:
如果您的新行以日期开头但不是新条目,它将不起作用。
试试这个
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);
注意几个惰性量词。
最后,我们检查下一句开头或文件末尾的数字是否存在。
单行选项需要点捕获任何字符,包括换行。
感谢所有意见
我能够使用以下正则表达式模式通过 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}))+)");
这是一个仅限 .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 选项),直到下一个字符是行首日期的开始(或直到没有更多字符).
我正在尝试构建一个正则表达式来拆分从 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 页面,但找不到解决我的问题的方法。所以也许这里有人可以给我提示以解决我的问题。
您可以先将此解决方法用于 Regex.Replace():
string pattern = @"(.)$\n(\D\D[^.]\D\D[^.]\D\D)";
string input = ""; // Your multiline input
string replacement = "";
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](.*)");
来创建您的群组。
限制:
如果您的新行以日期开头但不是新条目,它将不起作用。
试试这个
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);
注意几个惰性量词。
最后,我们检查下一句开头或文件末尾的数字是否存在。
单行选项需要点捕获任何字符,包括换行。
感谢所有意见
我能够使用以下正则表达式模式通过 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}))+)");
这是一个仅限 .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 选项),直到下一个字符是行首日期的开始(或直到没有更多字符).