我试图在Python中重现这个正则表达式:https://regex101.com/r/tP1bS4/2
示例entry
数据如下:
[ 10.0.7.58/54648 -> 31.221.26.40/80 (http response) ]-
|
| server = 31.221.26.40/80
| app = ???
| lang = none
| params = anonymous
| raw_sig = 1:Content-Type,?Last-Modified,?Cache-Control,?Expires,Date,Connection=[keep-alive]:Keep-Alive,Accept-Ranges:
|
基本上我想最终得到一个包含两个元素的组:服务器IP和端口,从第三行开始。
这是我的Python尝试;
server = re.findall( '\| server[ \s]+= (.*)\/(.*)\n', entry, re.DOTALL)
print server
这给了我server
组:
[('31.221.26.40', '80\n| app = ???\n| lang = none\n| params = anonymous\n| raw_sig = 1:Content-Type,?Last-Modified,?Cache-Control,?Expires,Date,Connection=[keep-alive]:Keep-Alive,Accept-Ranges:\n|')]
正如您所看到的那样,\n
没有分裂。预期结果将是:
[('31.221.26.40', '80')]
答案 0 :(得分:2)
我会尝试 -
re.findall(r'\| server[ \s]+= (.*)\/([^\/\W]*)',string)
空间规范化\|\s*server\s*=\s*([^/]*?)/([^/\W]*)
答案 1 :(得分:2)
让我清楚一些事情。 re.DOTALL
修饰符使.
符号匹配任何符号,包括换行符。带有DOTALL的.*
子模式将字符串与结尾匹配。
如果您使用'\| server[ \s]+= (.*)\/(.*)\n'
,则第一个.*
匹配到最后/
,第二个.*
匹配到最后\n
,因为它是贪婪(也就是说,引擎会抓取所有其余的字符串,然后回溯以试图适应后续的子模式)。
由于您的数据在一行中,因此 希望.
与换行符匹配。因此,解决问题的最简单方法是使用
server = re.findall(r'\|\s*server\s*=\s*(.*?)/(.*)', entry)
请参阅regex demo
然而,只有当我们不知道期望什么字符时,点匹配才有用。您可以使用字符类来增强正则表达式:
server = re.findall(r'\|\s*server\s*=\s*([^\s/]+)/(\d+)', entry)
另一个regex demo(注意效率提高了x2倍)
([^\s/]+)
匹配空格以外的1个或多个字符,而/
和\d+
匹配1位或更多位数。
答案 2 :(得分:0)
没有正则表达式:
import io
data = '''[ 10.0.7.58/54648 -> 31.221.26.40/80 (http response) ]-
|
| server = 31.221.26.40/80
| app = ???
| lang = none
| params = anonymous
| raw_sig = 1:Content-Type,?Last-Modified,?Cache-Control,?Expires,Date,Connection=[keep-alive]:Keep-Alive,Accept-Ranges:
|'''
for line in io.StringIO(data):
if line.startswith('| server '):
print(line[13:].rstrip().split('/'))
如果您不确切知道“server”之后的空格或制表符的数量,您可以这样更改:
if line.startswith('| server'):
print(line.split()[3].split('/'))