如何将多个正则表达式编译为一个正则表达式



早上好,我需要将几个正则表达式编译成一个模式正则表达式如下:

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})$'

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

109.169.248.247-[12/2015年12月:18:25:11+0100]";POST/administrator/index.php HTTP/1.1";200 4494〃;http://almhuette-raith.at/administrator/"quot;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))

显然,它不是那样工作的。如何做对?

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

你有两个选择:

  • 通过交替连接正则表达式: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)(最后一个是非捕获组,如果你不想捕获其内容,这是首选(

最新更新