【问题标题】:How to compile several regex into one如何将多个正则表达式编译为一个
【发布时间】:2021-05-13 06:34:22
【问题描述】:

早上好,我需要把几个正则表达式编译成一个模式 正则表达式是这样的:

reg_ip = r'(?P<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
reg_meth = r'(?P<METHOD>GET|POST|PUT|DELETE|HEAD)'
reg_status = r'\s(?P<STATUS>20[0-9]|30[0-9]|40[0-9]|50[0-9])\s'
reg_400 = r'\s(?P<STATUS_400>40[0-9])\s'
reg_500 = r'\s(?P<STATUS_500>50[0-9])\s'
reg_url = r'"(?P<URL>htt[p|ps]:.*?)"'
reg_rt = r'\s(?P<REQ_TIME>\d{4})$'

为 apache access.log 中的字符串编写正则表达式:

109.169.248.247 - - [12/Dec/2015:18:25:11 +0100] "POST /administrator/index.php HTTP/1.1" 200 4494 "http://almhuette-raith.at/administrator/ " "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" 4374

试图用这样的代码编译它:

some_pattern =  re.compile(reg_ip.join(reg_meth).join(reg_status))

显然它不是那样工作的。怎么做才对?

【问题讨论】:

标签: python-3.x regex


【解决方案1】:

你需要一些正则表达式之间的胶水

你有两个选择:

  • 通过交替加入正则表达式:regex1|regex2|regex3|... 并使用全局搜索
  • 添加缺少的粘合 betweek 正则表达式:例如,在 reg_status 和 reg_url 之间,您可能需要添加 r'[^"]+' 以跳过下一个数字

交替的问题是你可以在任何地方找到正则表达式。因此,您可以在 url 中找到例如单词 post(或数字)。

所以对我来说,第二种选择更好。

这是我要用的胶水:

import re

reg_ip = r'(?P<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
reg_meth = r'(?P<METHOD>GET|POST|PUT|DELETE|HEAD)'
reg_status = r'\s(?P<STATUS>20[0-9]|30[0-9]|40[0-9]|50[0-9])\s'
#reg_400 = r'\s(?P<STATUS_400>40[0-9])\s'
#reg_500 = r'\s(?P<STATUS_500>50[0-9])\s'
reg_url = r'"(?P<URL>https?:[^"]+)"'
reg_rt = r'\s(?P<REQ_TIME>\d{4})$'

some_pattern =  re.compile(reg_meth + r'\s+[^]]+\s*"' + reg_status + r'[^"]+' + reg_url + r'\s*"[^"]+"\s*' + reg_rt)
print(some_pattern)

line = '109.169.248.247 - - [12/Dec/2015:18:25:11 +0100] "POST /administrator/index.php HTTP/1.1" 200 4494 "http://almhuette-raith.at/administrator/" "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" 4374'

print(some_pattern.search(line))

对于胶水,这些是我用的:

\s*   : Capture any 'whitespace' 0 or more times
\s+   : Capture any 'whitespace' 1 or more times
[^X]+ : Where 'X' is some character; Capture any non-X characters one or more times

顺便说一句:

这个htt[p|ps] 不正确。您可以简单地使用 https? 代替。或者如果你想用组来做:htt(p|ps)http(?:p|ps)(最后一个是非捕获组,如果你不想捕获它的内容,这是首选)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 2015-12-28
    • 2020-07-25
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多