【问题标题】:Parse Apache log in PHP using a sing named REGEX使用名为 REGEX 的 sing 在 PHP 中解析 A​​pache 日志
【发布时间】:2018-05-30 02:36:10
【问题描述】:

我偶然发现了这个命名组正则表达式规则,其中作者声称这个单一的正则表达式能够匹配世界上使用最广泛的 Web 服务器之一的所有可能输出:

(?:(?<network.srcIpv4>(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?<network.srcIpv6>[:\-0-9a-fA-F]+?)|(?<network.srcHost>.+?)) - (?:-|(?<user.username>.+)) \[(?<time>.*)\]\"(?<application.cmd>(?<application.http.method>[A-Z]+)\s(?:(?<application.proto>.*?)://)?(?<network.fqdn>[ˆ/]*?)(?:\:(?<network.dstPort>d+))?(?<file.path>/.*?)?(?:\?(?<application.http.queryString>.*?))?(?: HTTP/(?<application.http.version>[0-9\.]+)?))\" (?<application.http.status>\d+) (?<application.len>\d+)(?:"(?:-|(?<application.http.referrer>.*))")?(?:"(?:-|(?<application.http.userAgent>.*))")?

但是当我尝试here 时,它似乎没有工作。我知道可以将单个正则表达式写入 Apache 日志,如下所示:

^(\S+) \S+ \S+ \[([^\]]+)\] "([A-Z]+)[^"]*" \d+ \d+ "[^"]*" "([^"]*)"$

但我更喜欢使用命名正则表达式,因为它们很容易理解,任何人都可以帮我弄清楚第一个正则表达式有什么问题吗?谢谢。

PS:为了论证,假设我的正则表达式在 PHP 中。

【问题讨论】:

  • 您不能在组名中使用.。它应该以 _ 或 ASCII 字母开头,然后最多可以包含 31 个单词字符。
  • 我已删除它们,并再次尝试,但没有成功。我认为,问题出在别的地方。
  • 查看this regex demo. 替换为_,它工作正常。你需要匹配什么字符串?
  • 好吧,我已经尝试了很多示例,但它们都不起作用! 218.1.111.50 - - [13/Mar/2005:10:36:12 -0500] "GET http://www.yahoo.com/ HTTP/1.1" 403 2898 "-" "Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)" 或者24.23.244.160 - - [13/Mar/2005:13:48:40 -0500] "GET /scripts/..%25%35%63../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 1041 "-" "-" 不知道大家是否熟悉sotM 34 challenge。消息人士称,之前命名的正则表达式可以捕获该数据集的所有可能输出。
  • 您的图案中有一些拼写错误

标签: regex apache logging


【解决方案1】:

你可以使用

^(?:(?<network_srcIpv4>(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?<network_srcIpv6>[:\-0-9a-fA-F]+?)|(?<network_srcHost>.+?)) - (?:-|(?<user_username>.+)) \[(?<time>.*)\] \"(?<application_cmd>(?<application_http_method>[A-Z]+)\s(?:(?<application_proto>.*?)://)?(?<network_fqdn>[^/]*?)(?:\:(?<network_dstPort>\d+))?(?<file_path>/.*?)?(?:\?(?<application_http_queryString>.*?))?(?: HTTP/(?<application_http_version>[0-9\.]+)?))\" (?<application_http_status>\d+) (?<application_len>\d+) (?:"(?:-|(?<application_http_referrer>.*))")? (?:"(?:-|(?<application_http_userAgent>.*))")$

请参阅regex demo

除了正则表达式中的各种拼写错误(\d 之前缺少\ 以匹配数字,ˆ 而不是^)和缺少空格,问题是组名只能以_ 或ASCII 字母,然后最多可以有 31 个字字符。因此,所有. 都应替换为_ 或删除。

注意我添加了^$ 线锚(还要注意启用该行为的m 多行修饰符)。如果您不需要整个字符串/行匹配,则可以删除锚点。

【讨论】:

  • 非常感谢你。你拯救了我的一天:)。编辑 !此正则表达式旨在捕获所有可能的访问日志输出。我已经尝试过了,它没有捕获 错误日志,例如:[Sun Mar 13 10:36:11 2005] [error] [client 218.1.111.50] Directory index forbidden by rule: /var/www/html/[Mon Mar 07 00:07:01 2005] [error] Spurious SSL handshake interrupt [Hint: Usually just one of those OpenSSL confusions!?]
  • @U.User 那些没有遵循你的正则表达式。只需为这种样式创建一个新模式。
  • 感谢您的确认。在我想出一个命名组正则表达式之前,我总是可以使用以下内容! :^\[([^\]]+)\] \[([^\]]+)\] (?:\[client ([^\]]+)\])?\s*(.*)$
猜你喜欢
  • 2011-11-28
  • 2013-05-04
  • 2010-09-14
  • 2016-07-23
  • 2011-07-30
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
相关资源
最近更新 更多