正则表达式 - 在 Python 中将连字符后的文本提取到字典中

4
我将尝试从日志中提取数据并放入字典中。以下是第一行的样子:
146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622

我已经将IP提取到字典中,但在尝试获取用户名(连字符后面)时,我得到了这个输出:
{'host': '146.204.224.152', 'user_name': ' '}

这是我使用的代码:
for item in re.finditer("(?P<host>[0-9]+(?:\.[0-9]+){3})(P<user_name>(?<=- )*\s)", logdata):
print(item.groupdict())

我对正则表达式一窍不通。请问我做错了什么?

我想要输出的结果应该像这样:

{'host': '146.204.224.152', 'user_name': 'feest6811'}
1个回答

1
首先,这里有一个错别字,(P<user_name> 应该是 (?P<user_name>
正则表达式引擎从左到右解析字符串(至少默认情况下如此,没有那么多支持从右到左解析的正则表达式库)。逐个字符读取字符串,并尝试将这些字符与模式匹配。它无法跳过消耗子模式之间的字符串部分(即使那些使正则表达式索引前进的子模式,即非lookarounds)。因此,(?<=- )* 是一个正向回顾后发断言,要求当前位置的左侧立即有一个-和空格,并且由于*,可以出现零次或多次。这个*量词使得在此使用回顾后发断言的整个想法变得毫无意义,因为它停止了对任何内容的要求。所以,这只是用\s捕获一个空格。
你所需要做的就是使用\s+-\s+\s+\S+\s+来消耗日期和用户之间的部分。
(?P<host>[0-9]+(?:\.[0-9]+){3})\s+-\s+(?P<user_name>\S+)

请查看正则表达式演示

\s+-\s+ 匹配一个被一个或多个空格包围的 -\s+\S+\s+ 匹配一个被一个或多个空格包围的一个或多个非空白字符。


1
谢谢您的回答和解释。这解决了我的问题。 - Amos Turin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接