【问题标题】:regex - extract website address from log file正则表达式 - 从日志文件中提取网站地址
【发布时间】:2011-03-16 16:01:42
【问题描述】:

我在编写正则表达式查询以提取日志文件中的所有网站地址时需要帮助。日志文件的每一行都包含一堆信息(IP 地址、协议、字节、请求的网站等...)。

具体来说,我想删除以“http://”开头并以特定“.ENDING”结尾的所有内容,其中我指定“ENDING = com, biz, net, tv, info” 我不关心完整的网址(即:http://www.google.com/bla/page2=blablabla,只需 http://www.google.com)。这个正则表达式查询更难的部分是我希望它在包含 .com 或 .info 或 .biz 作为子域的域(即:http://www.google.com.MaliciousWebsite.com)上获取在这种情况下,要在 google.com 上捕获完整的域,而不是在 google.com 上截断它?

我以前从未写过正则表达式查询,所以我尝试使用在线参考图表 (http://www.addedbytes.com/cheat-sheets/regular-expressions-cheat-sheet/) 但我很挣扎。这是我目前所拥有的:

"\A[http://]\Z[\.][com,info,biz,tv,net]"

*抱歉 URL 中的间距,但 stackoverflow 正在标记它们,因为我是新手,所以我最多只能发布 2 个。

感谢您的帮助。

已更新:根据迄今为止每个人的出色反馈,我认为编写此规则会更好,以便它适用于介于(http或https)之间的所有内容) 和 (无效的 URL 字符:?,!,@,#,$,%,^,&,*,(,),[,{,},],|,/,',",;,)

这将确保所有 TLD 都被抓取,并且 google.com.bad.website.com 等网站也被抓取。到目前为止,这是我的模型:

"\A[https?://]'?!(!@#$%^&*()-=[]{}|\'";,<>)"

再次感谢大家的帮助。

【问题讨论】:

  • 除了您列出的扩展名之外,还有其他扩展名(例如 .gov 和 .edu)。你只想捕捉那些吗?
  • 我没有列出所有这些,但我会彻底扫描以获取所有 TLD 扩展名,如您列出的 gov、edu、tv、net 等...
  • 这很好,但请记住,它们有很多,而且它们会定期更改。 IP 地址或特殊域名呢? http://192.168.0.1 是有效的,http://localhost 也是如此。还要考虑端口号(即http://example.com:8080),我不知道您是否要捕获这些。恕我直言,您应该抓住所有内容,直到域名中不允许出现的第一个字符。
  • 这可能会使一切变得更简单,因为您建议只需抓住所有内容,直到出现不允许的字符。所以 ?![\?|\=|\@|\#|\$|] 的结尾应该有效吗?
  • 在这种情况下,我的回答应该对你有用。顺便说一句 - 除非你使用我不熟悉的正则表达式风格,[]\Z, 不要做你认为他们做的事。您上面示例的想法似乎是\A(http://)(.+?)\.(com|info|biz|tv|net),但我不确定您是否要使用\Z

标签: regex


【解决方案1】:

你可以试试这个表达式:

\b((?:http://)(?:.)*(?:\.)(?:com|info|biz|tv|net))

你可以看看这里的描述:)

r"""
\b               # Assert position at a word boundary
(                # Match the regular expression below and capture its match into backreference number 1
   (?:              # Match the regular expression below
      http://          # Match the characters “http://” literally
   )
   (?:              # Match the regular expression below
      .                # Match any single character that is not a line break character
   )*               # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   (?:              # Match the regular expression below
      \.               # Match the character “.” literally
   )
   (?:              # Match the regular expression below
                       # Match either the regular expression below (attempting the next alternative only if this one fails)
         com              # Match the characters “com” literally
      |                # Or match regular expression number 2 below (attempting the next alternative only if this one fails)
         info             # Match the characters “info” literally
      |                # Or match regular expression number 3 below (attempting the next alternative only if this one fails)
         biz              # Match the characters “biz” literally
      |                # Or match regular expression number 4 below (attempting the next alternative only if this one fails)
         tv               # Match the characters “tv” literally
      |                # Or match regular expression number 5 below (the entire group fails if this one fails to match)
         net              # Match the characters “net” literally
   )
)
"""

【讨论】:

    【解决方案2】:

    这将捕获 http 或 https 后跟 :// 和不包含空格或斜杠的域名。
    请注意,对于各种编程语言,正则表达式存在一些缺陷。您可能需要通过\/ 转义/ 或在Java 中您必须通过\\ 加倍\

    https?://[^ /]+\.(?:com|info|biz|tv|net)
    

    【讨论】:

      【解决方案3】:
      ^http\:\/\/(.+)\.(com|info|biz|tv|net)
      

      将捕获以指定 tld 结尾的 http 领域中的所有域,但也会捕获诸如:http://test.commercial.ly 之类的所有域。我没有添加结尾斜线,因为我不确定域上是否总是有结尾斜线,但如果域上总是有结尾斜线,您可以简单地在结尾添加 /的正则表达式。如果你并不总是有一个结束斜线,那可能会给你一些误报。 如果需要,您还可以添加 https 支持。 您确定要指定顶级域名吗?或者您想获取任何顶级域名吗?

      【讨论】:

      • 我更愿意获取任何顶级域名。我不认为有办法表达,所以我想我必须手动输入它们。
      • 类似 ^http\:\/\/(.+)\.([a-z]{2,4})/ 之类的东西会抓取所有具有任何 tld 的域。使用 [a-z]{2,4} 从 a-z 中选择长度为 2-4 个字符的任何字符。我不确定是否有任何 tld 大于 4 个字符,但如果有,请调整该部分。
      【解决方案4】:

      \A[http://]\Z[\.][.*][com,info,biz,tv,net]?![\.]

      不确定您使用的是哪种类型的正则表达式,但您似乎正在尝试查找同时包含“.com、net 等”的地址的点。 AND "/",或更具体的可能是:以 .com 结尾,并且不在另一个 '.' 之前

      所以 .com.com 无效,但 .com/ 或 .com 有效

      【讨论】:

      • 是的,重点是提取请求的域。但是,我看到域请求伪装成使用google.com.malware.badguywebsite.info 使用户相信它是合法图像站点。我想捕获整个字符串,而不是让它看到 www.google.com 并切断域的其余部分。这有意义吗?
      • 啊,我想我明白你的意思了。正确,仅 .com 不是一个足够好的规则。它需要检查以确保它是 .com 而不是再次跟随 [.]。
      【解决方案5】:

      嗯,你好 user662772:

      好的,我不是要刻薄,但您考虑过使用 awk 吗?它会将您的日志文件拆分为多个字段,然后您可以简单地打印您所追求的字段。 Bonus awk 进行正则表达式模式匹配和替换。

      但你问的是正则表达式:

      我正在使用 Perl 的正则表达式:

      http.*(\.com|\.org|\.net)

      woops 必须双重转义反斜杠。

      【讨论】:

      • 我确实可以访问珍珠查询,所以我愿意接受任何一个/或。我都不熟悉,所以我不知道哪个会更容易。因此,我只是开始研究正则表达式。您可以使用 awk 在珍珠中提供它吗?
      【解决方案6】:

      不确定您使用的是哪种正则表达式语言,所以我将使用 .NET 语法。怎么样:

      @"^https?://[^?/#\s\r]+"
      

      它并不完美,但real spec for domain names is a beasthttp://https:// 的存在应该足以告诉您有一个域名正在路上。

      字符类should be fine中的?#,但我没有机会检查它。您可能需要使用 \ 转义它们。

      此外,这还将捕获端口号。如果您不想这样,请将: 添加到否定字符类中。


      编辑:PCRE 版本应该是这样的:

      ^https?:\/\/[^?\/#\s\r]+
      

      不过,我最近没有使用过 PCRE,因此您可能想与使用过的人核实一下。我不确定 PCRE 中的字符类中需要对哪些字符进行转义。

      【讨论】:

      • 我将从这里对 PCRE 进行更多研究。感谢您对新手的耐心等待!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      相关资源
      最近更新 更多