0

我正在尝试使用C#拆分一个包含区域的 SQL 脚本,使用Regex.Split()这些区域我似乎无法获得模式 - 我真的很纠结正则表达式的概念,并且在大多数情况下发现它完全令人困惑,尽管我确实理解它是实现以下目标的最佳解决方案。

输入字符串(下面是 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*

我只是似乎无法得到它!对我想要的输出的任何帮助表示赞赏:)

谢谢。

4

1 回答 1

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更容易检查,并想象您"--#region"的 SQL 中有一个字符串包含发生了什么?!)。
  • 要创建新行,请不要使用"\r\n"特定于环境的行,而是使用Environment.NewLine
  • sr.Peek()不应用于测试文件/流的结尾。有一个为此设计的属性:StreamReader.EndOfStream.
于 2013-07-23T13:52:29.230 回答