我有一个像
这样的文字rrr
ttt
yyyy
zzz
cc
iii
o
我需要在空行之间匹配块。所以,结果应该是:
0.
rrr
ttt
1.
yyyy
zzz
cc
2.
iii
o
尝试
var m = System.Text.RegularExpressions.Regex.Match(text, @"([a-zA-Z]+\r\n)+");
它不起作用。
答案 0 :(得分:3)
我只是想补充一些解释:
Regex(@"(.+((\r\n)|$))+")
稍短,也应与您的文本块匹配,因为:
.+
匹配除换行符之外的所有内容(\r\n)|$)
匹配新行或字符串的结尾(.+((\r\n)|$))+
匹配多个非空行text.Split(new[] { "\r\n\r\n" }, StringSplitOptions.RemoveEmptyEntries)
此外,还有关于正则表达式性能的讨论。我比较了m.rogalski,正则表达式(预编译)和带有BenchmarkDotNet的string.split解决方案的答案,这是一种常见的微基准解决方案。我没有将输出写入控制台,而是将其放入列表中。
以下是示例文本的基准测试结果:
BenchmarkDotNet=v0.10.1, OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Pentium(R) CPU B970 2.30GHz, ProcessorCount=2
Frequency=2241012 Hz, Resolution=446.2270 ns, Timer=TSC
[Host] : Clr 4.0.30319.42000, 32bit LegacyJIT-v4.6.1586.0
DefaultJob : Clr 4.0.30319.42000, 32bit LegacyJIT-v4.6.1586.0
Method | Mean | StdDev | Gen 0 | Allocated |
---------------- |---------- |---------- |------- |---------- |
TestRegExp | 5.1306 us | 0.0402 us | 1.1607 | 1.41 kB |
TestLists | 1.1866 us | 0.0106 us | 0.3395 | 408 B |
TestStringSplit | 1.3574 us | 0.0103 us | 0.6971 | 784 B |
我们能观察到什么?
答案 1 :(得分:2)
您可以在阅读文件时执行此操作:
// create a placeholder for processed lines
List<List<string>> _output = new List<List<string>>();
using (StreamReader reader = new StreamReader(File.OpenRead(filePath)))
{
int i = 0; // create indexer
_output.Add(new List<string>()); // add new sequence
_output.Last().Add(i.ToString() + "."); // insert sequence indexer
string line = string.Empty;
while( (line = reader.ReadLine()) != null)
{
if(string.IsNullOrWhiteSpace(line))
{
i++;
_output.Add(newList<string>());
_output.Last().Add(i.ToString() + ".");
}
else
{
_output.Last().Add(line);
}
}
}
然后您可以使用以下方法将其写入文本文件:
using (StreamWriter writer = new StreamWriter(File.OpenWrite(filePath)))
{
foreach(List<string> lines in _output)
{
foreach(string line in lines)
{
writer.WriteLine(line);
}
writer.WriteLine(line);
}
}
如果那不是文件(未指定)而是string
,则可以使用StringReader
代替StreamReader
和StringWriter
代替StreamWriter
对于其他想因为“非正则表达”答案或其他b而想要进行投票的人....
答案 2 :(得分:1)
我会选择产生群组的简单解决方案:
private static IEnumerable<IEnumerable<string>> GetGroups(IEnumerable<string> source)
{
var grouped = new List<string>();
foreach(var el in source)
{
if(!string.IsNullOrWhiteSpace(el))
grouped.Add(el);
else if(grouped.Any())
{
yield return grouped;
grouped = new List<string>();
}
}
if(grouped.Any())
yield return grouped;
}
用法:
var input = @"rrr
ttt
yyyy
zzz
cc
iii
o";
var res = GetGroups(input.Split(Environment.NewLine.ToCharArray()));
foreach(var r in res)
{
Console.WriteLine(string.Join(",",r));
}
答案 3 :(得分:0)
简单,使用nested groups:
using System.Text.RegularExpressions;
MatchCollection findings = new Regex(@"((.|(\n.))+)|((\n\n)((.|(\n.))+))").Matches(text);
for(int i = 0; i < findings.Count; i++) {
int groupIndex = findings[i].Groups[1].Length > 0 ? 0 : 6;
string match = findings[i].Groups[groupIndex].ToString();
Console.WriteLine(i+".");
Console.WriteLine(match);
}
您可以测试特定的正则表达式here。结果是在组1或6中(如上面的代码片段所示)。
我不知道为什么当前接受的答案是非正则表达式解决方案......
答案 4 :(得分:0)
你可以试试这个:
string input = "your text here";
string reg = @"([a-zA-Z]+\r\n)+";
var m = (text, reg, RegexOptions.Multiline);