如何改进这个正则表达式以在其他情况下工作?

2024-07-06 04:20:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我可以拆分这个字符串:

199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245

使用此正则表达式:

'([(\d\.)]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

那么如何改进这个正则表达式来拆分这种字符串(其中有internet地址而不是IP):

unicomp6.unicomp.net - - [01/Jul/1995:00:00:06 -0400] "GET /shuttle/countdown/ HTTP/1.0" 200 3985

这类字符串(双引号之间有双引号,我没有最后一个数字

frank.mtsu.edu - - [03/Jul/1995:02:41:15 -0400] "GET /images/" HTTP/1.0" 404 -

谢谢!你知道吗


Tags: 字符串iphttpgetnet地址historyinternet
2条回答

对于这种情况|运算符的含义或是有用的,对于第二个示例,您可以将表达式修改为:

'([(\d\.)]+|[a-z\d\.]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

请注意,这假设所有地址仅由小写字母、数字和点组成。 编辑:在@tripleee注释之后,我必须承认地址可能包含更多不同的字符,因此我添加了更宽容的解决方案:

'([(\d\.)]+|[^ ]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

这一个假设地址可能包含任何不是空格的字符。如果这是太宽容,请随时改进早期版本。 如评论中所述,它是多余的,可以用

'([^ ]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

要使它与最后一个case一起工作,只需将最后一个(\d+)替换为(\d+|-),正如前面@solarc所建议的那样

我不知道你到底想做什么,但你的正则表达式不是很具体,因为它的立场。下面是一个可以改进的建议解决方案。它看起来很复杂,但一旦坏了也不算太坏。你知道吗

^(\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b|\w+\.\w+\.(?:net|com|gov|edu))\s-\s-\s(\[[0-9]{2}\/\w{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}\s-[0-9]{4}\])\s(\"[^\"]+\")\s(.*)$

查看https://regex101.com/r/ojIGIA/3查看它的实际运行情况,并阅读右侧栏中的解释。你知道吗

编辑:我意识到我在regex的IP地址部分漏掉了一个?,我也忘了转义一个",因为我没有考虑python的味道。修复并更新了正则表达式和链接。你知道吗

现在我有更多的时间来解释我所做的事情。上述正则表达式可以按如下方式拆分。
^行首

(启动捕获组1

\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b这是捕获IP地址。如果你不太担心的话,你可以做一些像\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}这样的事情,这取决于你想要多精确。这将匹配所有有效的IP地址,但它也将匹配一些无效的。你知道吗

|或运算符

\w+\.\w+\.(?:net|com|gov|edu)这是一个非常基本的URL捕获示例。你知道吗

)结束捕获组1

\s-\s-\s与“--”完全匹配

^ {CD12>},这是我在中间捕获日期和其他东西的建议。它将需要调整,完全取决于你想要什么。这也是捕获组2。你知道吗

\s空格

(\"[^\"]+\")在匹配的这一点上匹配倒逗号中的所有内容。捕获第3组。你知道吗

\s空格

(.*)匹配所有其他内容直到结束,并放入捕获组4。你知道吗

$行尾

现在这些都只是建议,因为我不知道你到底想做什么,但希望这有帮助,给你一些想法。你知道吗

注意,我使用了\s而不是空格。使用空格没有错,我个人喜欢使用\s,因为它对我来说更容易阅读。你知道吗

相关问题 更多 >