2

入力ファイルでは、さまざまな条件に応じて、正規表現を使用して多くの文字列操作(検索/置換)を行う必要があります。たとえば、コンテンツの1つのブロックが条件を満たしている場合は、前のブロックに移動して、そのブロックで置換を行う必要があります。

このため、コンテンツを多くのサブストリングに分割して、前のブロック(ここでは前のサブストリング)に戻ることができるようにしています。正規表現の置き換えを行います。ただし、ファイルの内容が多い場合(または、サブ文字列の数が多い場合)、プログラムは途中でハングします。

これがコードスニペットです。

string content = string.Empty;
string target_content = string.Empty;
string[] active_doc_nos;
byte[] content_bytes;
FileInfo input_fileinfo = new FileInfo(input_file);
long file_length = input_fileinfo.Length;
using (FileStream fs_read = new FileStream(input_file, FileMode.Open, FileAccess.Read))
{
    content_bytes = new byte[Convert.ToInt32(file_length)];
    fs_read.Read(content_bytes, 0, Convert.ToInt32(file_length));
    fs_read.Close();
}
content = ASCIIEncoding.ASCII.GetString(content_bytes);
if (Regex.IsMatch(content, "<\\?CLG.MDFO ([^>]*) LEVEL=\"STRUCTURE\""))
{
    #region Logic-1: TWO PAIRS of MDFO-MDFC-s one pair following the other
    content = Regex.Replace(content, "(<\\?CLG.MDFO)([^>]*)(LEVEL=\"STRUCTURE\")", "<MDFO_VALIDATOR>$1$2$3");
    string[] MDFO_Lines = Regex.Split(content, "<MDFO_VALIDATOR>");
    active_doc_nos = new string[MDFO_Lines.GetLength(0)];
    active_doc_nos[0] = Regex.Match(MDFO_Lines[0], "ACTIVE DOC=\"([^>]*)\"\\s+").ToString();
for (int i = 1; i < MDFO_Lines.GetLength(0); i++)
{
    active_doc_nos[i] = Regex.Match(MDFO_Lines[i], "ACTIVE DOC=\"([^>]*)\"\\s+").ToString();
    if (Regex.IsMatch(MDFO_Lines[i - 1], "(<\\?CLG.MDFC)([^>]*)(\\?>)(<\\S*\\s*\\S*>)*$"))
    {
        MDFO_Lines[i - 1] = Regex.Replace(MDFO_Lines[i - 1], "(<\\?CLG.MDFC)([^>]*)(\\?>)(<\\S*\\s*\\S*>)*$", "<?no_smark?>$1$2$3$4");
        if (Regex.IsMatch(MDFO_Lines[i - 1], "^<\\?CLG.MDFO ([^>]*) ACTION=\"DELETED\""))
        {
            MDFO_Lines[i - 1] = Regex.Replace(MDFO_Lines[i - 1], "^<\\?CLG.MDFO ([^>]*) ACTION=\"DELETED\"", "<?no_bmark?><?CLG.MDFO $1 ACTION=\"DELETED\"");
        }
        if (active_doc_nos[i] == active_doc_nos[i - 1])
        {
            MDFO_Lines[i] = Regex.Replace(MDFO_Lines[i], "^<\\?CLG.MDFO ([^>]*) " + active_doc_nos[i], "<?no_smark?><?CLG.MDFO $1 " + active_doc_nos[i]);
        }
    }
}
foreach (string str_piece in MDFO_Lines)
{
   target_content += str_piece;
}
byte[] target_bytes = ASCIIEncoding.ASCII.GetBytes(target_content);
using (FileStream fs_write = new FileStream(input_file, FileMode.Create, FileAccess.Write))
{
    fs_write.Write(target_bytes, 0, target_bytes.Length);
    fs_write.Close();
}

このタスクを達成するための他のオプションはありますか?

4

1 に答える 1

1

あなたのデータを見ずに言うのは難しいですが、あなたの正規表現のいくつかのこの部分が原因である可能性があると私は疑っています:

(<\\S*\\s*\\S*>)*

はandに\Sも一致するため、すべてがオプションであり、量指定子がネストされているため、正規表現のこの部分が壊滅的なバックトラッキングにつながる可能性があります。<>

これらの部品を に置き換えるとどうなります(?>(<\\S*\\s*\\S*>))*か?

于 2012-09-20T16:38:12.990 に答える