我正在尝试使用C#
来分割包含区域的SQL脚本,使用Regex.Split()
我似乎无法获得模式 - 我真的很难与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*
我似乎无法得到它!我希望的输出的任何帮助赞赏:)
感谢。
答案 0 :(得分:2)
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
。