2

我想拆分以下字符串:

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

期望的结果是:

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

我发现最接近的是使用 shlex.split,但是这会删除内部引号,结果如下:

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

任何建议将不胜感激。

编辑:

还需要多次拆分,例如:

“数量 [*,'EXTRA 05',*] [*,'EXTRA 09',*]”

至:

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

4

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

正则表达式模式必须如下所示:

'|'表示或

所以正则表达式模式表达了两个部分 RE:
(?! )[^[]+?(?= *\[)

\[.+?\]

第一部分 RE :

核心是[^[]+
括号定义了一组字符。符号^在第一个括号之后[,这意味着该集合被定义为所有不是符号后面的字符^
目前[^[]表示不是左括号 [ 的任何字符,+并且由于在此 set 定义之后有一个,[^[]+表示其中的字符序列没有左括号

现在,在 之后有一个问号[^[]+:这意味着捕获的序列必须在问号之后的符号之前停止。
这里,紧随其后的?(?= *\[)先行断言,由(?=....)表示它是肯定的先行断言和 的信号组成 *\[,最后一部分是捕获的序列必须在其前面停止的序列。 *\[表示:零、一个或多个空格,直到左括号(需要反斜杠\来消除[作为一组字符的开头的含义)。

在核心前面还有(?! )一个否定的前瞻断言:有必要使这个部分RE只捕获以空白开头的序列,因此避免捕获连续的空白。去掉这个(?! ),你会看到效果。

第二部分 RE :

\[.+?\]表示:左括号字符 [,由.+?(与除 之外的任何字符匹配的点\n)捕获的字符序列,该序列必须在结束括号字符]之前停止,这是要捕获的最后一个字符。

.

编辑

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

结果

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

!!

于 2013-11-29T12:36:26.233 回答
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',*]"

我认为这正是您正在寻找的。如果我错了,请告诉我,或者您需要对代码进行一些解释。我希望它有帮助

于 2013-11-29T11:11:41.113 回答
0

假设您想要一个在空格而不是引号中分割的通用解决方案:我不知道有任何 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
于 2013-11-29T11:20:23.950 回答
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"']

于 2020-06-04T22:58:25.477 回答