用正则读取文本文件



以下是我写的用于从文本文件阅读的方法。在阅读时,我需要将行字符串与给定的正则匹配,如果它匹配,则需要将行字符串添加到集合中。

private static void GetOrigionalRGBColours(string txtFile)
{
    string tempLineValue;
    Regex regex = new Regex(@"^d+.?d* d+.?d* d+.?d* SRGB$");
    using (StreamReader inputReader = new StreamReader(txtFile))
    {
        while (null != (tempLineValue = inputReader.ReadLine()))                     
        {
            if (regex.Match(tempLineValue).Success
                && tempLineValue != "1 1 1 SRGB"
                && tempLineValue != "0 0 0 SRGB")
            {
                string[] rgbArray = tempLineValue.Split(' ');
                RGBColour rgbColour = new RGBColour() { Red = Convert.ToDecimal(rgbArray[0]), Green = Convert.ToDecimal(rgbArray[1]), Blue = Convert.ToDecimal(rgbArray[2]) };
                originalColourList.Add(rgbColour);
            }
        }
    }
} 

当该方法用于具有28653行的4MB的文本文件时,它需要 3分钟才能完成上述方法。另外,由于上述运行,originalColourList填充了582个项目。

任何人都可以指导如何提高这种方法的性能?实际的文本文件大小可能会增加到60MB

fyi-
REGEX的右匹配:0.922 0.833 0.855 SRGB
正则匹配正则匹配:/srgb/setrgbcolor load def
txt文件最初是一个邮局文件,我将其保存为用于使用C#的TXT文件。

如果您像这样重写的话:

Regex regex = new Regex(@"^d+(.d*)? d+(.d*)? d+(.d*)? SRGB$");

注意两个重要的更改:

  1. 每个.都用一个后斜切逃脱,以使得正则匹配字面的点,而不是任何字符。
  2. 每个.及以后的d*是一个可选的组,而不是.本身是可选的。

原始正则速度很慢,因为d+.?d*包含连续的量词(+?*)。当Regex引擎试图匹配一条以长序列数字开始时,这会导致过度回溯。例如,在我的计算机上,包含10,000个零的线需要超过四秒钟匹配。修订后的正则需要小于四毫秒,改进了1000x。

如果通过

RegexOptions.Compiled | RegexOptions.ECMAScript

作为Regex构造函数的第二个参数。ECMAScript告诉Regex引擎将d视为[0-9],忽略了您不在乎的Unicode数字,例如(藏族7)。

根据您的记录格式,您可以比使用正则表达式更快地解析。不知道文件的所有内容,但是从您的两个示例中,这比使用优化的正则速度快30%。

        decimal r;
        decimal g;
        decimal b;
        string rec;
        string[] fields;
        List<RGBColour> originalColourList = new List<RGBColour>();
        using (StreamReader sr = new StreamReader(@"c:temprgb.txt"))
        {
            while (null != (rec = sr.ReadLine()))
            {
                if (rec.EndsWith("SRGB"))
                {
                    fields = rec.Split(' ');
                    if (fields.Length == 4 
                        && decimal.TryParse(fields[0], out r) 
                        && decimal.TryParse(fields[1], out g) 
                        && decimal.TryParse(fields[2], out b)
                        && (r+g+b !=0)
                        && (r != 1  && g != 1 && b!=1)
                        )
                    {
                        RGBColour rgbColour = new RGBColour() { Red = r, Green = g, Blue = b };
                        originalColourList.Add(rgbColour);
                    }
                }
            }
        }

IF将在任何条件是错误的一旦短路,如果一切都是正确的,那么您不再需要将所有值转换为十进制。我在大约12.5秒内对此进行了600万行。

相关内容

  • 没有找到相关文章

最新更新