使用REGEX处理文件内容,而不是逐行处理
本文关键字:处理 逐行 REGEX 文件 使用 | 更新日期: 2023-09-27 18:24:34
我正试图使用C#
通过Regex.Split()
来分割一个包含区域的SQL脚本,而我似乎无法理解这种模式——我真的很难理解Regex的概念,在大多数情况下都觉得它完全令人困惑,尽管我确实认为它是实现以下目标的最佳解决方案。
输入字符串(下面是100'000*,因此我的方法缓慢)
--#region someregioncomment
aaaa
bbbb
--#endregion
其中,每个返回为'r'n
。
输出Dictionary<string, string>
密钥:
--#region someregioncomment
值:
aaaa'r'nbbbb
目前我正在做这件事:
Dictionary<string, string> regionValues = new Dictionary<string, string>();
using (StringReader sr = new StringReader(SSBS))
{
string strCurrentRegion = "";
string strCurrentRegionContents = "";
while (sr.Peek() != -1)
{
string strCurrentLine = sr.ReadLine();
if (strCurrentLine.Contains("--#region"))
{
strCurrentRegion = strCurrentLine;
}
if (string.IsNullOrEmpty(strCurrentRegion))
{
continue;
}
else if (strCurrentLine.Contains("--#endregion"))
{
regionValues.Add(strCurrentRegion, strCurrentRegionContents);
strCurrentRegion = "";
}
else
{
strCurrentRegionContents += ("'r'n" + strCurrentLine);
}
}
}
然而,我觉得这可以通过Regex
模式和Regex.Split()
相结合来实现——我似乎不知道这个模式应该是什么样子。。。
我曾经尝试过:
(--#region.*?)'n
(--#region)'w*
我好像就是不明白!感谢对我想要的输出的任何帮助:)
谢谢。
String.Split
和Regex
的问题是它将整个文件加载到内存中。那么,为什么不用StreamReader
一行一行地阅读脚本呢?
Dictionary<string, string> regions = new Dictionary<string, string>();
string regionName = null;
StringBuilder regionString = new StringBuilder();
using (StreamReader streamReader = File.OpenText("MyFile.txt"))
{
while (!streamReader.EndOfStream)
{
string line = streamReader.ReadLine();
if (line.StartsWith("--#region ")) // Beginning of the region
{
regionName = line.Substring(10);
}
else if (line.StartsWith("--#endregion")) // End of the region
{
if (regionName == null)
throw new InvalidDataException("#endregion found without a #region.");
regions.Add(regionName, regionString.ToString());
regionString.Clear();
}
else if (regionName != null) // If the line is in a region
{
regionString.AppendLine(line);
}
}
}
小心使用字典。如果文件包含多个具有相同名称的区域。它会崩溃的。
少数建议:
- 使用
StringBuilder
而不是串联字符串(以获得更好的性能) - 使用
String.StartsWith
而不是String.Contains
有两个原因:性能(StartWith
更容易检查,假设您的SQL中有一个包含"--#region"
的字符串,会发生什么?!) - 要创建新行,请不要使用特定于环境的
"'r'n"
,而是使用Environment.NewLine
sr.Peek()
不应用于测试文件/流的末尾。为此设计了一个属性:StreamReader.EndOfStream