繁体   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