【问题标题】:Regex take too long to match the result正则表达式花费太长时间来匹配结果
【发布时间】:2023-04-06 22:25:02
【问题描述】:

我有这个正则表达式模式

<(\d+)>(\d+\.\d+|\d{4}\-\d+\-\d+\s+\d{2}:\d{2}:\d{2})(?:\..*?)*\s+(ALER|NOTI)

这是我的输入(根本不匹配)

<150>2010-12-29 18:11:30.883 -0700 192.168.2.145 80 192.168.2.87 2795 "-" "-" GET HTTP 192.168.2.145 HTTP/1.1 200 36200 0 1038 544 192.168.2.221 80 540  SERVER DEFAULT PASSIVE VALID /joomla/ "-" http://192.168.2.145/joomla/index.php?option=com_content&view=a be4d44e8f3986183a87991398c1c212e=1;      be4d44e8f3986183a87991398c1c212e=1

这将返回不匹配结果,但输出结果需要很长时间。由于我在一秒钟内有一千条日志/输入,因此每个日志/输入的完成速度应该非常快。有时它会达到 CPU 100%。

谁能帮我解决这个正则表达式问题?

谢谢

【问题讨论】:

    标签: java regex perl


    【解决方案1】:

    由于表达式(?:\..*?)* 可以匹配的方式很多,您会遇到灾难性的回溯。可能需要检查数百万个匹配项,随着字符串中的点数呈指数增长。要修复它,您可以更改:

    (?:\..*?)*\s+
    

    到这里:

    \..*\s
    

    【讨论】:

      【解决方案2】:

      看起来您正在寻找一些日期/时间/等。有关 ALER/NOTI 行的信息。 难道你不能先通过 grepping ALER/NOTI 来解析这些行吗? 那么在那些有趣的行上运行正则表达式可能会容易得多(并且可能会简化正则表达式)。

      【讨论】:

        【解决方案3】:

        由于您没有提供有效的示例,因此唯一要说明的原因是它为什么慢
        这个(?:\..*?)* 是不是很奇怪。元时期。匹配任何内容,包括文字
        时期。该表达式表示如果存在文字句点,则获取它并一直到 \s。
        但是,文字句点是可选的。

        (?:\.(?:(?!\s(?:ALER|NOTI)).)*?)?\s+(ALER|NOTI)
        

        这本身就很奇怪。展开后可以查看。

        (?:
            \.
            (?:
                (?!\s(?:ALER|NOTI)).
            )*?
        )?
        \s+
        (ALER|NOTI)
        

        【讨论】:

          猜你喜欢
          • 2019-10-27
          • 2016-05-15
          • 1970-01-01
          • 2023-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-12
          相关资源
          最近更新 更多