Python 将字符串解析为元组列表

Python 将字符串解析为元组列表,python,python-2.7,Python,Python 2.7,输入:'(tagname1,tagvalue1),(tagname2,tagvalue2),(tagname3,tagvalue3),(tagname4,tagvalue4) 输出:[(“tagname1”、“tagvalue1”)、(“tagname2”、“tagvalue2”)、(“tagname3”、“tagvalue3”)、(“tagname4”、“tagvalue4”)] 我有一个解决方案,但它只有在输入包含每个元素的引号时才起作用:“tagname1”、“tagvalue1”… im

输入:
'(tagname1,tagvalue1),(tagname2,tagvalue2),(tagname3,tagvalue3),(tagname4,tagvalue4)

输出:
[(“tagname1”、“tagvalue1”)、(“tagname2”、“tagvalue2”)、(“tagname3”、“tagvalue3”)、(“tagname4”、“tagvalue4”)]

我有一个解决方案,但它只有在输入包含每个元素的引号时才起作用:
“tagname1”、“tagvalue1”…

import ast
ast.literal_eval(input_string)
在我的情况下,我收到:
ValueError:格式错误的字符串


是否有任何解决方案可以让它工作(也请查看空格)?

尝试另一种方法,使用正则表达式:

>>> import re
>>> s = '(tagname1, tagvalue1),(tagname2,tagvalue2), ( tagname3, tagvalue3 ), (tag name4,tag value4)'
>>> e = '\(\s?(.*?)\s?,\s?(.*?)\s?\)'
>>> re.findall(e, s)
[('tagname1', 'tagvalue1'), ('tagname2', 'tagvalue2'), ('tagname3', 'tagvalue3'), ('tag name4', 'tag value4')]

Burhan建议的另一种方法是利用反向引用的能力。您可以阅读更多关于反向引用的信息

您可以看到正则表达式演示

注意:

我还使用了
pattern.finditer()
,因为这样可以通过文本中的所有模式结果进行迭代。从re.finditer文档:

finditer(pattern,string,flags=0)返回一个迭代器 针对RE的所有非重叠匹配的MatchObject实例 字符串中的模式。字符串从左到右扫描,并匹配 按找到的顺序返回。空匹配项包含在 结果,除非他们触及另一场比赛的开始


下面是一个处理多个空格(非单词字符)的
re.findall
变体:


注意单词字符(包括空格)后面的非贪婪闭包(重复限定符),
[\w\s]*?
。这样可以确保捕获每个标记名/值的所有单词,但不包括所有前导空格和尾随空格。这就是为什么上面正确地捕获了
“tag value4”

另一种非正则方法:

def string_to_tuples(s):
    def tuple_strip(s):  # Wrapper to pass to map
        return s.strip(" ()")

    sl = map(tuple_strip, s.split(","))
    return zip(sl[::2], sl[1::2])
这将产生:

>>> string_to_tuples('(tagname1, tagvalue1),(tagname2,tagvalue2), ( tagname3, tagvalue3 ), (tag name4,tag value4)')
[('tagname1', 'tagvalue1'), ('tagname2', 'tagvalue2'), ('tagname3', 'tagvalue3'), ('tag name4', 'tag value4')]

只要标记不能以
(空格)、
,或
开头或结尾,并且不包含任何
s,它就可以工作。

Bleh nevermind,我的解决方案显然是错误的。这太完美了@Chris_Rands谢谢,修复了它。它仍然不能处理多个空格。标记名称4,标记值4-输出中缺少。我错过了这个案例(中间的空格)。修好了。现在它将剥离引导和尾随空间,但保留中间的空间。正则表达式对我来说是一种巫术D
def string_to_tuples(s):
    def tuple_strip(s):  # Wrapper to pass to map
        return s.strip(" ()")

    sl = map(tuple_strip, s.split(","))
    return zip(sl[::2], sl[1::2])
>>> string_to_tuples('(tagname1, tagvalue1),(tagname2,tagvalue2), ( tagname3, tagvalue3 ), (tag name4,tag value4)')
[('tagname1', 'tagvalue1'), ('tagname2', 'tagvalue2'), ('tagname3', 'tagvalue3'), ('tag name4', 'tag value4')]