在双引号和方括号中分割字符串
我刚刚开始使用Python,我试图用双引号和方括号分割字符串。在双引号和方括号中分割字符串
例子:
10.223.157.186 - - [15/Jul/2009:14:58:59 -0700] "GET /assets/js/lowpro.js HTTP/1.1" 200 10469
通缉结果:
ip: 10.223.157.186
identity: -
username: -
time: [15/Jul/2009:15:50:35 -0700]
request: "GET /assets/js/lowpro.js HTTP/1.1"
status: 200
size: 10469
我想他们在 '空间' 分裂,但它也将[]
和""
之间拆分部分。就像这样:
['10.223.157.186', '-', '-', '[15/Jul/2009:14:58:59', '-0700]', '"GET', '/assets/js/lowpro.js', 'HTTP/1.1"', '200', '10469']
我见过像许多可能的解决方案:
-
shlex
(我的蟒蛇不会导入) data = line.strip().split('\"')
但给人一种说不出的输出太老了 说实话我真的不明白这个正则表达式,我也不知道我是否可以导入就像是shlex。
您可以使用正则表达式:
line = """10.223.157.186 - - [15/Jul/2009:14:58:59 -0700] "GET /assets/js/lowpro.js HTTP/1.1" 200 10469\n"""
import re
log_line = re.compile('(?P<ip>[^ ]*) (?P<identity>[^ ]*) (?P<username>[^ ]*) \\[(?P<time>[^\\]]*)\\] "(?P<request>[^"]*)" (?P<status>[^ ]*) (?P<size>[^ ]*)$')
for key, value in log_line.match(line).groupdict().iteritems():
print "%s: %s" % (key, value)
你也可以使用一个分析器,通过@ jpmc26建议。
我要去反对“正则表达式谷物”,并说使用解析器;解析器是正则表达式之上的复杂度级别,通常使用正则表达式来定义其语法部分。我选择的图书馆是pyparsing
。你会使用这样的:
>>> s = '10.223.157.186 - - [15/Jul/2009:14:58:59 -0700] "GET /assets/js/lowpro.js HTTP/1.1" 200 10469'
>>> from pyparsing import ZeroOrMore, Regex
>>> parser = ZeroOrMore(Regex(r'\[[^]]*\]') | Regex(r'"[^"]*"') | Regex(r'[^ ]+'))
>>> for i in parser.parseString(s): print i
...
10.223.157.186
-
-
[15/Jul/2009:14:58:59 -0700]
"GET /assets/js/lowpro.js HTTP/1.1"
200
10469
注意,标记的顺序(这些Regex
对象的东西)是很重要的。通过首先放置方括号和双引号标记,它们优先。如果你把最后一个放在第一位,它就不能正常工作。这样做的一个好处就是扩展比正则表达式更容易(只支持常规语言操作,除非你做了一堆疯狂的查找工作)。例如,解析器可以帮助你分开那些括号或者引号,如果你决定想要的话,并且做一点工作,你可以改变解析器以允许嵌套括号或者引号。 (后者是真正的正则表达式不能做的事情。你也许能够得到一个带有环视扩展的正则表达式来做到这一点,但在我看来这并不值得。解析器更强大,而且在我经验,更易于理解和使用。)
请注意,解析器不会返回一个列表或可迭代。它返回自己的特殊对象:
>>> parser.parseString(s)
(['10.223.157.186', '-', '-', '[15/Jul/2009:14:58:59 -0700]', '"GET /assets/js/lowpro.js HTTP/1.1"', '200', '10469'], {})
>>> type(parser.parseString(s))
<class 'pyparsing.ParseResults'>
我想我也应该解释我的正则表达式。
\[[^]]*\]
:这只是匹配一对方括号,可选地带有中间的东西。\[
表示需要以方括号开始。[^]]
是字符类(只是正则表达式中的一组字符);外括号使它成为一个角色类。^
告诉它“字符列表中的其他内容”,内部]
只是字符列表。所以这部分只是“除]
以外的任何东西”。*
的意思是“零个或多个以前的东西”,所以它的意思是“零个或多个字符,而不是]
”。最后是\]
,这意味着它需要以]
结尾。初始的[
和最后的]
必须使用\
进行转义,因为它们通常用于指示字符类。"[^"]*"
:这几乎与最后一个相同。"
表示它必须以双引号开头。[^"]
是和以前一样的角色类;它意味着“除双引号之外的任何内容”。*
仍然意味着“零或多个”。最后的"
只是表示它必须以引用结尾。所以这只是“零个或多个包围双引号的字符”。[^ ]+
:[^ ]
是又一个同类的角色类。它只是意味着“除了空间以外的任何字符”,因为字符列表是一个空格。+
的意思是“以前的一件或多件事”(类似于*
,除了它至少需要一件)。所以这是“一个或多个非空间字符”。
的Regex
对象之间的操作者|
只是“或” -ing的不同的令牌一起,使得解析器只要它可以匹配这三种可能的令牌之一吐出的令牌。
感谢您的快速回答! – user3523150 2014-12-05 08:12:07
@ user3523150没问题。如果我们的答案之一解决了您的问题,请考虑接受它。 – jpmc26 2014-12-05 21:48:52
如果你没有'shlex',你会介意告诉我们你正在运行的是什么版本的Python(应该是Python在交互式提示符下输出的第一个东西)? – Kevin 2014-12-04 21:08:31
这可能是一个学习一些关于正则表达式的好机会...... – 2014-12-04 21:09:15
我刚刚意识到你的问题说你想处理引号,但你的例子实际上并没有这样做。 – jpmc26 2014-12-04 22:32:04