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.SplitRegexファイル全体をメモリにロードすることです。では、スクリプトを 1 行ずつ読んでみません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理由は 2 つあります: パフォーマンス (チェックが簡単で、SQL に何が起こるかStartWithを含む文字列があると想像してください!)。"--#region"
  • "\r\n"新しい行を作成するには、環境固有の which を使用しないでくださいEnvironment.NewLine
  • sr.Peek()ファイル/ストリームの終わりをテストするために使用しないでください。このために設計されたプロパティがあります: StreamReader.EndOfStream.
于 2013-07-23T13:52:29.230 に答える