我有一个这样的字符串:
this is "a test"
我试图在Python中写一些东西,通过空格分割它,同时忽略引号中的空格。我想要的结果是:
['this', 'is', 'a test']
PS,我知道你会问“如果引号中有引号会发生什么,在我的应用程序中,这永远不会发生。
我有一个这样的字符串:
this is "a test"
我试图在Python中写一些东西,通过空格分割它,同时忽略引号中的空格。我想要的结果是:
['this', 'is', 'a test']
PS,我知道你会问“如果引号中有引号会发生什么,在我的应用程序中,这永远不会发生。
当前回答
由于性能原因,re似乎更快。下面是我的解决方案,使用最小贪婪操作符,保留外部引号:
re.findall("(?:\".*?\"|\S)+", s)
结果:
['this', 'is', '"a test"']
它将像aaa“bla blub”bbb这样的结构放在一起,因为这些标记没有被空格分隔。如果字符串包含转义字符,你可以这样匹配:
>>> a = "She said \"He said, \\\"My name is Mark.\\\"\""
>>> a
'She said "He said, \\"My name is Mark.\\""'
>>> for i in re.findall("(?:\".*?[^\\\\]\"|\S)+", a): print(i)
...
She
said
"He said, \"My name is Mark.\""
请注意,这也通过模式的\S部分来匹配空字符串“”。
其他回答
嗯,好像找不到“回复”按钮了…不管怎样,这个答案是基于Kate的方法,但正确地分割了包含转义引号的子字符串,并删除了子字符串的开始和结束引号:
[i.strip('"').strip("'") for i in re.split(r'(\s+|(?<!\\)".*?(?<!\\)"|(?<!\\)\'.*?(?<!\\)\')', string) if i.strip()]
这适用于'这是' a \\\"test\\\"\\\'s子字符串' '这样的字符串(不幸的是,为了防止Python删除转义,这个疯狂的标记是必要的)。
如果返回列表中的字符串不需要转义,您可以使用稍微修改过的函数版本:
[i.strip('"').strip("'").decode('string_escape') for i in re.split(r'(\s+|(?<!\\)".*?(?<!\\)"|(?<!\\)\'.*?(?<!\\)\')', string) if i.strip()]
根据你的用例,你可能还想检查csv模块:
import csv
lines = ['this is "a string"', 'and more "stuff"']
for row in csv.reader(lines, delimiter=" "):
print(row)
输出:
['this', 'is', 'a string']
['and', 'more', 'stuff']
要解决某些Python 2版本中的unicode问题,我建议:
from shlex import split as _split
split = lambda a: [b.decode('utf-8') for b in _split(a.encode('utf-8'))]
我用shlex。拆分来处理七千万行鱿鱼日志,太慢了。所以我换成了re。
请尝试这个,如果你有性能问题与shlex。
import re
def line_split(line):
return re.findall(r'[^"\s]\S*|".+?"', line)
你需要从内置的shlex模块中分离。
>>> import shlex
>>> shlex.split('this is "a test"')
['this', 'is', 'a test']
这应该是你想要的效果。
如果你想保留引号,那么你可以传递posix=False kwarg。
>>> shlex.split('this is "a test"', posix=False)
['this', 'is', '"a test"']