簡體   English   中英

我怎樣才能優化這個正則表達式的性能?

[英]how can i optimize the performance of this regular expression?

我正在使用正則表達式將文本限定引號中未包含的逗號替換為制表符空格。 我正在通過 SSIS 中的腳本任務對文件內容運行正則表達式。 文件內容超過 6000 行。 我看到了一個在文件內容上使用正則表達式的例子,看起來像這樣

String FileContent = ReadFile(FilePath, ErrInfo);        
Regex r = new Regex(@"(,)(?=(?:[^""]|""[^""]*"")*$)");
FileContent = r.Replace(FileContent, "\t");

可以理解的是,該替換可以在大小合適的文件上度過美好的時光。

有沒有更有效的方法來運行這個正則表達式? 逐行讀取文件並每行運行正則表達式會更快嗎?

您似乎正在嘗試將逗號分隔值 (CSV) 轉換為制表符分隔值 (TSV)。

在這種情況下,您應該嘗試查找 CSV 庫,並使用該庫讀取字段(必要時將其轉換為 TSV)。

或者,您可以檢查每一行是否有引號並相應地使用更簡單的方法。

問題在於前瞻,它在每個命令上一直查找到末尾,導致 O(n 2 ) 復雜度,這在長輸入時很明顯。 您可以通過在替換時跳過引號來一次性完成:

Regex csvRegex = new Regex(@"
    (?<Quoted>
        ""                  # Open quotes
        (?:[^""]|"""")*     # not quotes, or two quotes (escaped)
        ""                  # Closing quotes
    )
    |                       # OR
    (?<Comma>,)             # A comma
    ",
RegexOptions.IgnorePatternWhitespace);
content = csvRegex.Replace(content,
                        match => match.Groups["Comma"].Success ? "\t" : match.Value);

在這里,我們匹配自由命令和引用的字符串。 Replace方法接受一個帶有條件的回調,該條件檢查我們是否找到逗號,並相應地替換。

最簡單的優化是

Regex r = new Regex(@"(,)(?=(?:[^""]|""[^""]*"")*$)", RegexOptions.Compiled);
foreach (var line in System.IO.File.ReadAllLines("input.txt"))
    Console.WriteLine(r.Replace(line, "\t"));

我沒有對其進行分析,但如果加速很大,我不會感到驚訝。

如果這還不夠,我建議一些體力勞動:

var input = new StreamReader(File.OpenRead("input.txt"));

char[] toMatch = ",\"".ToCharArray ();
string line;
while (null != (line = input.ReadLine()))
{
    var result = new StringBuilder(line);
    bool inquotes = false;

    for (int index=0; -1 != (index = line.IndexOfAny (toMatch, index)); index++)
    {
        bool isquote = (line[index] == '\"');
        inquotes = inquotes != isquote;

        if (!(isquote || inquotes))
            result[index] = '\t';
    }
    Console.WriteLine (result);
}

PS:我認為@"\t""\t" \t" 的錯字,但也許不是:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM