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

时间:2019-01-16 16:43:13

标签: python regex pyspark

我可以分割此字符串:

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

使用此RegEx:

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

那么如何改进此RegEx来拆分这种字符串(有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 -

谢谢!

2 个答案:

答案 0 :(得分:0)

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

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

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

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

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

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

要使其与最后一种情况一起使用,只需将(\d+)的前面的(\d+|-)替换为@solarc

答案 1 :(得分:0)

我不确定您要做什么,但是您的正则表达式不是很具体。以下是可能有改进的建议解决方案。它看起来很复杂,但是一旦分解就还算不错。

^(\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可以看到它的实际效果,并进行解释,请阅读右侧栏。

编辑:我意识到我在正则表达式的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地址,但也将匹配一些无效的IP地址。

|或运算符

\w+\.\w+\.(?:net|com|gov|edu)这是一个非常基本的示例,显示了URL捕获的外观。

)结束捕获组1

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

(\[[0-9]{2}\/\w{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}\s-[0-9]{4}\])这是我建议在中间记录日期和其他内容。它将需要根据您的实际需要进行调整。这也是捕获组2。

\s一个空格

(\"[^\"]+\")在比赛的这一点上匹配逗号之间的所有内容。捕获组3。

\s空格

(.*)匹配其他所有内容直到结尾并将其放入捕获组4。

$行尾

现在这些都是建议,因为我不知道您到底想做什么,但希望这能对您有所帮助。

请注意,我使用\ s代替空格。使用空格没有什么问题,我个人喜欢使用\ s,因为它对我来说更容易阅读。