Python用空格分割字符串,除了在引号中的时候,但保留引号

问题描述 投票:1回答:4

我想拆分以下字符串。

数量[*,'EXTRA 05',*]

希望得到的结果是:

["数量", "[*,'EXTRA 05',*]"]

我找到的最接近的方法是使用shlex.split,但是这样做会去除内部引号,得到以下结果。

['数量', '[*,EXTRA 05,*]']

如果有什么建议,将非常感谢。

编辑。

还需要多次分割,如:

"数量 [*,'EXTRA 05',*] [*,'EXTRA 09',*]"

至:"数量","[*,EXTRA 05',*]","[*,EXTRA 09',*]"]

["数量","[*,'额外05',*]","[*,'额外09',*]"]

python split quotes spaces shlex
4个回答
4
投票

要处理字符串,基本的方法是使用正则表达式工具(模块 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',*]"]

正则表达式模式必须取消如下。

'|' 是指OR

所以,regex模式表达了两部分re。(?! )[^[]+?(?= *\[)\[.+?\]

第一部分RE 。

核心是 [^[]+ 括号中定义了一组字符。符号 ^ 在第一括号后 [ 这意味着该集合被定义为所有不在符号后面的字符 ^. 目前 [^[] 途径 任何非括号内的字符[ ]。 而且,由于有一个 + 集的这一定义后。[^[]+ 途径 方括号.

现在,有一个问号在 [^[]+ 意思是说,捕捉到的序列必须停在问号之后的符号之前。在这里,问号后面的内容是 ?(?= *\[) 这是一个前瞻性的断言,由以下几个部分组成 (?=....) 这意味着它是一个积极的前瞻性的断言,并且具有 *\[这最后一部分是指被捕捉到的序列必须在其前面停止。 *\[ 意味着:零,一个或多个空格,直到开括号(反斜杠)。\ 所需,以消除 [ 作为一组人物的开场白)。)

还有 (?! ) 在核心前面,它是一个消极的看前断言:有必要使这部分RE只抓住以空白开始的序列,所以避免抓住连续的空白。去掉这个 (?! ) 你就会看到效果。

第二部分RE:

\[.+?\] 意思是:开括号的字符 [ 捕捉到的字符序列,由 .+? (该点与除 \n),这个序列必须停在结尾的括号内的字符前面 ] 那是最后一个被抓住的字符。

.

编辑

string = "Quantity [*,'EXTRA 05',*] [*,'EXTRA 09',*]"
import re
print re.split(' (?=\[)',string)

结果

['Quantity', "[*,'EXTRA 05',*]", "[*,'EXTRA 09',*]"]

!!


1
投票

建议挑剔的人,这个算法不会把你通过的每个字符串都拆分好,只是像这样的字符串。

"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',*]"

我想这正是你要找的东西。如果我错了,请告诉我,或者如果你需要一些代码的解释。希望能帮到你


0
投票

假设你想要一个通用的解决方案,用于在空格处进行分割,但不用于引号中的空格。我不知道有什么Python库可以做到这一点, 但这并不意味着没有.

在没有已知的预先滚动的解决方案的情况下,我会简单地滚动自己的解决方案。扫描一个字符串寻找空格是比较容易的,然后使用 Python 的 slice 功能将字符串分割成你想要的部分。如果要忽略引号中的空格,你可以简单地包含一个标志,在遇到引号符号时打开和关闭空格感应。

这是我为了实现这个功能而编写的一些代码,它没有经过广泛的测试。

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

0
投票

试试这个

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"']

© www.soinside.com 2019 - 2024. All rights reserved.