我想拆分以下字符串:
数量 [*,'EXTRA 05',*]
期望的结果是:
["数量", "[*,'EXTRA 05',*]"]
我发现最接近的是使用 shlex.split,但是这会删除内部引号,结果如下:
['数量', '[*,EXTRA 05,*]']
任何建议将不胜感激。
编辑:
还需要多次拆分,例如:
“数量 [*,'EXTRA 05',*] [*,'EXTRA 09',*]”
至:
["数量", "[*,'EXTRA 05',*]", "[*,'EXTRA 09',*]"]
对待字符串,基本的方式是正则表达式工具(模块re)
鉴于您提供的信息(这意味着它们可能不充分),以下代码可以完成这项工作:
import re
r = re.compile('(?! )[^[]+?(?= *\[)'
'|'
'\[.+?\]')
s1 = "Quantity [*,'EXTRA 05',*] [*,'EXTRA 09',*]"
print r.findall(s1)
print '---------------'
s2 = "'zug hug'Quantity boondoggle 'fish face monkey "\
"dung' [*,'EXTRA 05',*] [*,'EXTRA 09',*]"
print r.findall(s2)
结果
['Quantity', "[*,'EXTRA 05',*]", "[*,'EXTRA 09',*]"]
---------------
["'zug hug'Quantity boondoggle 'fish face monkey dung'", "[*,'EXTRA 05',*]", "[*,'EXTRA 09',*]"]
正则表达式模式必须如下所示:
'|'表示或
所以正则表达式模式表达了两个部分 RE:
(?! )[^[]+?(?= *\[)
和
\[.+?\]
核心是[^[]+
括号定义了一组字符。符号^在第一个括号之后[,这意味着该集合被定义为所有不是符号后面的字符^。
目前[^[]表示不是左括号 [ 的任何字符,+并且由于在此 set 定义之后有一个,[^[]+表示其中的字符序列没有左括号。
现在,在 之后有一个问号[^[]+:这意味着捕获的序列必须在问号之后的符号之前停止。
这里,紧随其后的?是(?= *\[)先行断言,由(?=....)表示它是肯定的先行断言和 的信号组成 *\[,最后一部分是捕获的序列必须在其前面停止的序列。 *\[表示:零、一个或多个空格,直到左括号(需要反斜杠\来消除[作为一组字符的开头的含义)。
在核心前面还有(?! )一个否定的前瞻断言:有必要使这个部分RE只捕获以空白开头的序列,因此避免捕获连续的空白。去掉这个(?! ),你会看到效果。
\[.+?\]表示:左括号字符 [,由.+?(与除 之外的任何字符匹配的点\n)捕获的字符序列,该序列必须在结束括号字符]之前停止,这是要捕获的最后一个字符。
.
string = "Quantity [*,'EXTRA 05',*] [*,'EXTRA 09',*]"
import re
print re.split(' (?=\[)',string)
结果
['Quantity', "[*,'EXTRA 05',*]", "[*,'EXTRA 09',*]"]
!!
建议挑剔的人,该算法不会很好地分割你通过它的每个字符串,就像字符串一样:
"Quantity [*,'EXTRA 05',*] [*,'EXTRA 09',*]"
"Quantity [*,'EXTRA 05',*]"
"Quantity [*,'EXTRA 05',*] [*,'EXTRA 10',*] [*,'EXTRA 07',*] [*,'EXTRA 09',*]"
string = "Quantity [*,'EXTRA 05',*] [*,'EXTRA 09',*]"
splitted_string = []
#This adds "Quantity" to the position 0 of splitted_string
splitted_string.append(string.split(" ")[0])
#The for goes from 1 to the lenght of string.split(" "),increasing the x by 2
#The first iteration x is 1 and x+1 is 2, the second x=3 and x+1=4 etc...
#The first iteration concatenate "[*,'EXTRA" and "05',*]" in one string
#The second iteration concatenate "[*,'EXTRA" and "09',*]" in one string
#If the string would be bigger, it will works
for x in range(1,len(string.split(" ")),2):
splitted_string.append("%s %s" % (string.split(" ")[x],string.split(" ")[x+1]))
当我执行代码时,最后的拆分字符串包含:
['Quantity', "[*,'EXTRA 05',*]", "[*,'EXTRA 09',*]"]
splitted_string[0] = 'Quantity'
splitted_string[1] = "[*,'EXTRA 05',*]"
splitted_string[2] = "[*,'EXTRA 09',*]"
我认为这正是您正在寻找的。如果我错了,请告诉我,或者您需要对代码进行一些解释。我希望它有帮助
假设您想要一个在空格而不是引号中分割的通用解决方案:我不知道有任何 Python 库可以做到这一点,但这并不意味着没有。
在没有已知的预卷解决方案的情况下,我会简单地推出自己的解决方案。扫描字符串以查找空格,然后使用 Python 切片功能将字符串分成所需的部分相对容易。要忽略引号中的空格,您可以简单地包含一个标志,该标志打开遇到引号符号以打开和关闭空间感应。
这是我敲出来的一些代码,它没有经过广泛的测试:
def spaceSplit(string) :
last = 0
splits = []
inQuote = None
for i, letter in enumerate(string) :
if inQuote :
if (letter == inQuote) :
inQuote = None
else :
if (letter == '"' or letter == "'") :
inQuote = letter
if not inQuote and letter == ' ' :
splits.append(string[last:i])
last = i+1
if last < len(string) :
splits.append(string[last:])
return splits
尝试这个
def parseString(inputString):
output = inputString.split()
res = []
count = 0
temp = []
for word in output:
if (word.startswith('"')) and count % 2 == 0:
temp.append(word)
count += 1
elif count % 2 == 1 and not word.endswith('"'):
temp.append(word)
elif word.endswith('"'):
temp.append(word)
count += 1
tempWord = ' '.join(temp)
res.append(tempWord)
temp = []
else:
res.append(word)
print(res)
输入:
parseString('这是对拆分的“带引号的字符串”的“测试”')
输出:['This', 'is', '"a test"', 'to', 'your', 'split', '"string with quotes"']