【问题标题】:Python and Regular ExpressionsPython 和正则表达式
【发布时间】:2013-06-24 03:43:54
【问题描述】:

大家好,

我之前发布了类似的内容,因此如果您再次遇到此问题,我深表歉意。这一次,我会更具体,给你直接的例子,并准确地描述我想要的。基本上,我需要让原始数据看起来更漂亮:

str = '2011-06-1618:53:41222.222.2.22-somedomain.hi.comfw12192.10.215.11GET/965874/index.xls22233665588-0Mozilla/4.0 (compatible; MSI 5.5; Windows NT 5.1)'--55656-0.55-5874/659874540--'



more strings:
'2011-06-2150:36:1292.249.2.105-somedomain.hi.comfw12192.10.215.11GET/965874/ten.xls22233665588-0Mozilla/4.0 (compatible; MSI 6.0; Windows NT 5.1)'--55656-0.55-5874/659874540--'
'2011-01-1650:23:45123.215.2.215-somedomain.hi.comfw12192.10.215.11GET/123458/five.xls22233665588-0Mozilla/4.0 (compatible; MSI 7.0; Windows NT 5.1)'--55656-0.55-5874/659874540--'
'2011-02-1618:16:54129.25.2.119-thisdomain.hi.comfw12192.10.215.11GET/984745/two.xls22233665588-0Mozilla/4.0 (compatible; MSI 7.0; Windows NT 5.1)'--55656-0.55-5874/659874540--'
'2011-08-0525:22:16164.32.2.111-yourdomain.hi.comfw12192.10.215.11GET/85472/one.xls22233665588-0Mozilla/4.0 (compatible; MSI 8.0; Windows NT 5.1)'--55656-0.55-5874/659874540--'

在调试器中:

import re
str = '2011-06-1618:53:41222.222.2.22-somedomain.hi.comfw12192.10.215.11GET/965874/index.xls22233665588-0Mozilla/4.0 (compatible; MSI 5.5; Windows NT 5.1)'--55656-0.55-5874/659874540--'
domain = re.compile('^.*?(?=([fw].+?))')
domain.search(str).group()
'2011-06-1618:53:41222.222.2.22-somedomain.hi.com'
domain = domain.search(str).group()

所以为了获得域名,我需要去掉破折号(-)之前的所有内容,就在域名之前。我可以用这个 RE ([0-9]{3,5}).([0-9]{1,3}.){2}[0-9]{1,3}[- ] 但我不知道怎么说,找到该值并在它之后返回所有内容,但在 fw12 之前。

最后,我希望这些字符串看起来像这样,使用逗号(,)作为分隔符:

2011-08-05, 25:22:16, 164.32.2.111, yourdomain.hi.com, GET/85472/one.xls, Mozilla/4.0(兼容;MSI 8.0;Windows NT 5.1)

【问题讨论】:

  • 为了解析这个,无论你使用什么技术,你都需要有一些方法来区分域名的尾部与后面的任何内容。你能用英语表达如何做到这一点吗?以下文本是否始终为“fw12”并且域中是否没有该字符串?
  • 网络日志没有字段之间的分隔符?奇怪的配置:s
  • 是否所有的IP地址都在一个特定的范围内?如果不是,则可能很难构建一个能够识别“fwXX”部分结尾和 IP 地址开头的正则表达式。
  • 看起来很像您的小时值超过 24。这有点不寻常。还有54秒。什么?!

标签: python regex


【解决方案1】:

为了分隔每个字段,我建议你使用这个模式(然后你用你想要的分隔符加入匹配项):

(\d{4}-\d{2}-\d{2})(\d{2}:\d{2}:\d{2})(\d+(?:\.\d+){3})-([a-z.]+)fw\d+(?:\.\d+){3}(GET\/\d+\/[a-z.]+)[-\d]+([^'-]+)

【讨论】:

    【解决方案2】:

    首选但可能不可能的方法

    这看起来像(正如 MatToufoutu 指出的)一个 Apache 日志文件。如果确实如此,那么您可以使用apachelog 或类似的东西来处理它。您需要将 Apache 的 httpd.conf/apache2.conf 文件字符串用作格式化程序。因为我没有你的,所以我只是使用了apachelog 的文档中提供的那个:

    import apachelog
    
    format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" '
    log_line = """212.74.15.68 - - [23/Jan/2004:11:36:20 +0000] "GET /images/previous.png HTTP/1.1" 200 2607 "http://peterhi.dyndns.org/bandwidth/index.html" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2) Gecko/20021202" """
    
    p = apachelog.parser(format)
    data = p.parse(log_line)
    

    然后您可以通过访问data 的属性来访问日志文件的各个部分

    print "%s, %s, %s, %s, %s" % (data['%t'], data['%h'], data['%{Referer}i'], data['%r'], data['%{User-Agent}i'])
    

    获取输出

    [23/Jan/2004:11:36:20 +0000], 212.74.15.68, http://peterhi.dyndns.org/bandwidth/index.html, GET /images/previous.png HTTP/1.1

    使用正则表达式

    或者,您可以采用最初的方法并使用正则表达式来解析该行。以下应该工作。它们被分成命名的组,以便更容易 A) 阅读 B) 编辑 C) 理解:

    import re
    
    
    your_string = "2011-06-1618:53:41222.222.2.22-somedomain.hi.comfw12192.10.215.11GET/965874/index.xls22233665588-0Mozilla/4.0 (compatible; MSI 5.5; Windows NT 5.1)'--55656-0.55-5874/659874540--"
    
    pattern = re.compile(r'(?P<date>\d{4}(:?-\d{2}){2})(?P<time>(:?\d{2}:?){3})(?P<ip_address1>(:?\d{1,3}\.?){4})-(?P<domain>[\w\.]+)fw12(?P<ip_address2>(:?\d{1,3}\.?){4})(?P<get>(:?GET/(:?\d+/)).*?)\d+-0(?P<user_agent>.*?)\'--.*$')
    result = pattern.match(your_string)
    

    然后您可以使用result.group('groupname') 访问结果,例如:

    print "%s %s, %s, %s, %s, %s" % (result.group('date'), result.group('time'), result.group('ip_address1'), result.group('domain'), result.group('get'), result.group('user_agent'))
    

    哪个会返回:

    2011-06-16 18:53:41, 222.222.2.22, somedomain.hi.com, GET/965874/index.xls, Mozilla/4.0(兼容;MSI 5.5;Windows NT 5.1)

    由于这个方法处理的是正则表达式,所以我总是喜欢添加我的小免责声明:

    您正在解析数据。它取决于你和你对你需要多少容忍、卫生和验证的判断。您可能需要修改上述内容以更好地满足您的要求,并正确处理样本中未包含的真实数据。确保您了解正则表达式的作用,以便了解此代码的工作原理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2011-08-06
      • 1970-01-01
      相关资源
      最近更新 更多