Python 将双引号内的字符串与双引号匹配

Python 将双引号内的字符串与双引号匹配,python,regex,double-quotes,Python,Regex,Double Quotes,我有一个python字符串: string = '"/dev/null" "" "19/1333329478.9381399" 0 1 "cam-foo" 64 900.0 "Foo x rev scan of test" "/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py" 60.145855 2.034689' 我需要一个正则表达式,它给我这个字符串中每个元素的列表。

我有一个python字符串:

string = '"/dev/null" "" "19/1333329478.9381399" 0 1 "cam-foo" 64 900.0 "Foo x rev scan of test" "/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py" 60.145855 2.034689'
我需要一个正则表达式,它给我这个字符串中每个元素的列表。 元素:双引号中包含的任何数字或字符串。字符串可以包含双引号

我推出了这个正则表达式:

import re    
p = re.compile(r'"[^"]*"|[-\.\d]+')
p.findall(string)
['"/dev/null"', '""', '"19/1333329478.9381399"', '0', '1', '"cam-foo"', '64', '900.0', '"Foo x rev scan of test"', '"/usr/bin/env "', '"PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"', '" python app.py"', '60.145855', '2.034689']
正如您所看到的,我遗漏了字符串中的双引号部分应忽略元素内的双引号。我希望得到以下结果:

['"/dev/null"', '""', '"19/1333329478.9381399"', '0', '1', '"cam-foo"', '64', '900.0', '"Foo x rev scan of test"', '"/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py"', '60.145855', '2.034689']
而是有3个(或更多)元素

我只想要一个元素:

'"/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py"'

有人能帮我吗?

请将regex搜索令牌放在()中。 发生的情况是,re不会为每个查找返回列表。 选择正确的数组元素。 例如:

将返回一个m格式的列表,其每个元素根据()中包含的内容再次成为标记化列表。
通过这种方式,您可以检索所需语句的确切部分。

正则表达式的前半部分当前匹配一对双引号,其中包含零个或多个非双引号字符

r'"[^"]*"'
您可以通过更改在周围双引号内匹配的字符串来实现所需的结果

r'"(?:[^"]|"")*"'
这个正则表达式匹配一对围绕零个或多个字符串的双引号;每个字符串必须由一个非双引号字符或两个连续双引号组成。(
?:
将括号内的位标记为非捕获组;否则Python将只返回括号内的位。)

让我们将其插入完整的正则表达式:

% python
Python 2.7.2 (default, Mar 20 2012, 13:27:18) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> s = '"/dev/null" "" "19/1333329478.9381399" 0 1 "cam-foo" 64 900.0 "Foo x rev scan of test" "/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py" 60.145855 2.034689'
>>> for el in re.findall(r'"(?:[^"]|"")*"|[-\.\d]+', s): print(el)
... 
"/dev/null"
""
"19/1333329478.9381399"
0
1
"cam-foo"
64
900.0
"Foo x rev scan of test"
"/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py"
60.145855
2.034689
>>>

如果您只需要能够拆分此确切案例,则可以使用:

它不是正则表达式,但每次都能为您解决这个问题。

您可以使用它


那么你的意思是:p=re.compile(r'(“[^”]*”|[-\.\d]+)。如果是的话,我已经尝试过了,结果是一样的。这实际上是对
csv
模块的一个非常巧妙的使用。我推荐你!非常感谢你的解决方案!是的,我同意@jathanism,我认为我的问题应该采用这个解决方案。再次感谢!完全放弃
”“
around
PATH=…
可能不正确。非常感谢您的帮助,但不幸的是,我不能使用shlex有两个原因:正如J.F.Sebastian所说,它会下降”“'在字符串中。另一个原因是性能:我有一个很大的文件,而且速度非常慢。很公平,我在提出这个建议时没有考虑掉的双引号。这个正则表达式很有魅力。起初我想采用这个解决方案,但实际上我选择了@j-f-sebastian的解决方案(使用cvs模块)。您的解决方案和csv解决方案给了我相同的结果,它们以相同的方式解析日志,但我使用csv的列表比此解决方案的列表“更干净”(所有字符串本身没有双引号)。再次感谢您的努力,我对此表示感谢。
r'"(?:[^"]|"")*"'
% python
Python 2.7.2 (default, Mar 20 2012, 13:27:18) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> s = '"/dev/null" "" "19/1333329478.9381399" 0 1 "cam-foo" 64 900.0 "Foo x rev scan of test" "/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py" 60.145855 2.034689'
>>> for el in re.findall(r'"(?:[^"]|"")*"|[-\.\d]+', s): print(el)
... 
"/dev/null"
""
"19/1333329478.9381399"
0
1
"cam-foo"
64
900.0
"Foo x rev scan of test"
"/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py"
60.145855
2.034689
>>>
>>> import shlex
>>> s = '"/dev/null" "" "19/1333329478.9381399" 0 1 "cam-foo" 64 900.0 "Foo x rev scan of test" "/usr/bin/env ""PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH"" python app.py" 60.145855 2.034689'
>>> shlex.split(s)
['/dev/null', '', '19/1333329478.9381399', '0', '1', 'cam-foo', '64', '900.0', 'Foo x rev scan of test', '/usr/bin/env PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH python app.py', '60.145855', '2.034689']
>>> shlex.split(s)[-3]
'/usr/bin/env PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH python app.py'
>>> import csv
>>> from pprint import pprint
>>> pprint(list(csv.reader([string], delimiter=' ', quotechar='"')))
[
[
'/dev/null'
,
''
,
'19/1333329478.9381399'
,
'0'
,
'1'
,
'cam-foo'
,
'64'
,
'900.0'
,
'Foo x rev scan of test'
,
'/usr/bin/env "PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" python app.py'
,
'60.145855'
,
'2.034689'
]
]