我想知道分割字符串的最佳方法,该字符串的最后一个空间不在[, {, ( or "
内,由空格分隔。例如:
a = 'a b c d e f "something else here"'
b = 'another parse option {(["gets confusing"])}'
对于a,它应该解析为['a', 'b', 'c', 'd', 'e', 'f'], ["something else here"]
和b解析为['another', 'parse', 'option'], ['([{"gets confusing"}])']
现在我有这个:
def getMin(aList):
min = sys.maxint
for item in aList:
if item < min and item != -1:
min = item
return min
myList = []
myList.append(b.find('['))
myList.append(b.find('{'))
myList.append(b.find('('))
myList.append(b.find('"'))
myMin = getMin(myList)
print b[:myMin], b[myMin:]
我相信有更好的方法来做到这一点,我愿意接受所有的建议
匹配与分裂
有一个简单的解决办法。关键是要理解匹配和分裂是同一枚硬币的两面。当你说"匹配全部"时,这意味着"我不希望匹配的部分被分割",反之亦然。我们将匹配,而不是分割,最终你会得到相同的结果。
简化版
让我们从最简单的正则表达式开始,这样你就不会被很长的东西吓倒了:
{[^{}]*}|S+
这将匹配第二个字符串中的所有项-就像我们拆分(参见演示)
- 左侧的
|
交替匹配{braces}
的完整集合。 -
|
的右侧匹配任何非空白字符。
就是这么简单!
完整的正则表达式
我们还需要匹配"full quotes"
, (full parentheses)
和[full brackets]
。没问题,我们只要把它们加到备选项中。为了清楚起见,我将它们放在一个非捕获组(?:
中,以便S+
自行弹出,但没有必要。
(?:{[^{}]*}|"[^"]*"|([^()]*)|[[^][]*])|S+
看演示。
注释潜在改进
- 我们可以将带引号的字符串正则表达式替换为接受转义引号的正则表达式
- 我们可以用递归表达式替换大括号,括号和圆括号表达式,以允许嵌套结构,但您必须使用Matthew Barnett的(awesome)
regex
模块而不是re
- 该技术与匹配(或替换)模式的简单而美丽的技巧有关,除非…
如果你有问题请告诉我!
可以使用正则表达式:
import re
def parse(text):
m = re.search(r'(.*) ([[({"].*)', text)
if not m:
return None
return m.group(1).split(), [m.group(2)]
第一部分(.*)捕获以引号或圆括号括起的部分之前的所有内容,第二部分捕获以([{"
中的字符开头的所有内容。
如果你需要更健壮的东西,这有一个更复杂的正则表达式,但它将确保匹配开始标记,并使最后一个表达式成为可选的。
def parse(text):
m = re.search(r'(.*?)(?: ("[^"]*"|([^)]*)|[[^]]*]|{[^}]*}))?$', text)
if not m:
return None
return m.group(1).split(), [m.group(2)]
也许这个链接会有帮助:
用空格分隔字符串——保留带引号的子字符串——在Python
它解释了如何在用空格分隔字符串时保留带引号的子字符串。