C# 有没有一种使用正则表达式快速解析大文件的方法?

C# 有没有一种使用正则表达式快速解析大文件的方法?,c#,regex,algorithm,C#,Regex,Algorithm,问题: 非常非常大的文件,我需要逐行解析,从每行中得到3个值。一切正常,但解析整个文件需要很长时间。有可能在几秒钟内完成吗?它通常需要1分钟到2分钟的时间 示例文件大小为148208KB 我使用正则表达式解析每一行: 这是我的c#代码: private static void readtheline(int max、响应程序rp、字符串输入文件) { 列表速率=新列表(); 双计数器=1; 尝试 { 使用(var sr=newstreamreader(inputFile,Encoding.UTF

问题: 非常非常大的文件,我需要逐行解析,从每行中得到3个值。一切正常,但解析整个文件需要很长时间。有可能在几秒钟内完成吗?它通常需要1分钟到2分钟的时间

示例文件大小为148208KB

我使用正则表达式解析每一行:

这是我的c#代码:

private static void readtheline(int max、响应程序rp、字符串输入文件)
{
列表速率=新列表();
双计数器=1;
尝试
{
使用(var sr=newstreamreader(inputFile,Encoding.UTF8,true,1024))
{
弦线;
Console.WriteLine(“读取…”);
而((line=sr.ReadLine())!=null)
{

如果(counter现在,您每次调用
GetRateLine
时都会重新创建
Regex
,这在您每次读取一行时都会发生

如果预先使用一次,然后使用非静态方法,则可以节省正则表达式编译时间,这可能会提高速度

也就是说,这可能不会花费你几分钟到几秒钟的时间…

以及寻求帮助

  • 创建具有多个随机访问视图的持久化MMF。每个视图对应于文件的特定部分
  • 使用参数定义解析方法,如
    IEnumerable
    ,基本上是抽象一组未解析的行
  • 使用
    Parse(IEnumerable)
    作为任务操作,为每个MMF视图创建并启动一个TPL任务
  • 每个辅助任务都将一个已解析的数据添加到类型为的共享队列中
  • 另一个任务侦听BC()并处理工作任务已解析的所有数据
  • 请参阅MSDN上的


    必须说此解决方案适用于
    .NET Framework>=4

    而不是为每次调用
    GetRateLine
    重新创建正则表达式,而是提前创建它,将
    RegexOptions.Compiled
    选项传递给构造函数


    您可能还想尝试将整个文件读入内存,但我怀疑这是您的瓶颈。从磁盘读入~100MB应该不需要一分钟。

    简单地看一下,我会尝试一些方法

    首先,将文件流缓冲区至少增加到64kb:

    using (var sr = new StreamReader(inputFile, Encoding.UTF8, true, 65536))
    
    其次,构造一次正则表达式,而不是在循环中使用字符串:

    static readonly Regex rateExpression = new Regex(@"^\d{1,}.+\[(.*)\s[\-]\d{1,}].+GET.*HTTP.*\d{3}[\s](\d{1,})[\s](\d{1,})$", RegexOptions.IgnoreCase);
    //In GetRateLine() change to:
    Match match = rateExpression.Match(justALine);
    
    第三,通过让Responder.GetRate()返回列表或数组,使用单个列表实例

    // replace: 'rp.GetRate(rate)', with:
    rate = rp.GetRate();
    
    我会将名单预先分配到一个“合理”的限度:

    List<int> rate = new List<int>(10000);
    
    List rate=新列表(10000);
    

    您也可以考虑将编码从UTF-8更改为ASCII,如果可用的话,也可以满足您的特定需求。 评论

    一般来说,如果这真的需要缩短解析时间,那么您需要构建一个标记器并完全跳过正则表达式。由于您的输入格式看起来都是ascii且相当简单,这应该很容易做到,但可能比正则表达式更脆弱。最后,您需要权衡e对速度的需求与代码的可靠性和可维护性


    如果你需要一些手工解析的例子,请看

    我不是一个真正的专家,但我没有发现任何不合适的地方。简短回答:不,你不能在几秒钟内解析每一行150 mb的数据。是的,我也是这么想的,但我不确定我是否不够聪明,不能想出一些大的O符号来加快解析速度。试试com首先堆积你的正则表达式?
    regex-myregex=new-regex(@“…”,RegexOptions.Compiled);myregex.Match(etc);
    你逐行读取IO,速度很慢。如果可能,你应该一次性加载文本。否则,加载一大块文本,比如每次10MB。很多情况下,IO是瓶颈。
    // replace: 'rp.GetRate(rate)', with:
    rate = rp.GetRate();
    
    List<int> rate = new List<int>(10000);