Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用正则表达式读取文本文件_C#_.net_Regex_Stream - Fatal编程技术网

C# 使用正则表达式读取文本文件

C# 使用正则表达式读取文本文件,c#,.net,regex,stream,C#,.net,Regex,Stream,下面是我为从文本文件读取而编写的方法。在阅读时,我需要将行字符串与给定的正则表达式匹配,如果匹配,则需要将行字符串添加到集合中 private static void GetOrigionalRGBColours(string txtFile) { string tempLineValue; Regex regex = new Regex(@"^\d+.?\d* \d+.?\d* \d+.?\d* SRGB$"); using (StreamReader inputRe

下面是我为从文本文件读取而编写的方法。在阅读时,我需要将行字符串与给定的正则表达式匹配,如果匹配,则需要将行字符串添加到集合中

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

供参考-
正则表达式的右匹配:0.922 0.833 0.855 SRGB
正则表达式的匹配错误:/SRGB/setrgbcolor load def

txt文件最初是一个postscript文件,我已将其保存为txt文件,以便使用C#进行操作。

如果按如下方式重写,正则表达式将快得多:

Regex regex = new Regex(@"^\d+(\.\d*)? \d+(\.\d*)? \d+(\.\d*)? SRGB$");
注意两个重要的变化:

  • 每个
    都用反斜杠转义,以便正则表达式匹配文字点而不是任何字符
  • 每个
    \.
    和后面的
    \d*
    作为一个组是可选的,而不是
    \.
    本身是可选的
  • 原始正则表达式速度较慢,因为
    \d+。?\d*
    包含连续的(
    ++
    *
    )。当正则表达式引擎试图匹配以长数字序列开头的行时,这会导致过度的错误。例如,在我的机器上,包含10000个零的行需要超过四秒钟才能匹配。修改后的正则表达式所需时间不到四毫秒,提高了1000倍

    如果你通过的话,正则表达式可能会更快

    RegexOptions.Compiled | RegexOptions.ECMAScript
    

    作为
    Regex
    构造函数的第二个参数
    ECMAScript
    告诉正则表达式引擎将
    \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:\temp\rgb.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);
                        }
                    }
                }
            }
    
    decimalr;
    十进制g;
    十进制b;
    字符串记录;
    字符串[]字段;
    List ORIGINALCOURLIST=新列表();
    使用(StreamReader sr=new StreamReader(@“c:\temp\rgb.txt”))
    {
    while(null!=(rec=sr.ReadLine())
    {
    如果(记录EndsWith(“SRGB”))
    {
    字段=记录拆分(“”);
    如果(fields.Length==4
    &&decimal.TryParse(字段[0],输出r)
    &&decimal.TryParse(字段[1],out g)
    &&decimal.TryParse(字段[2],输出b)
    &&(r+g+b!=0)
    &&(r!=1&&g!=1&&b!=1)
    )
    {
    RGBColour RGBColour=新RGBColour(){Red=r,Green=g,Blue=b};
    原始颜色列表。添加(RGB颜色);
    }
    }
    }
    }
    

    只要任何条件为false,if就会短路,如果一切都为true,则不再需要将所有值转换为十进制。我用它在大约12.5秒内解析了600万行。

    如果您为您的正则表达式显示正确和错误的匹配,您可能会得到更好的答案。这可以帮助我们确定您的正则表达式是否确实是必需的。编辑以包含更多详细信息。非常好的解释。