如何从一个看起来像元组但包含无引号文本的字符串创建元组?

2024-03-29 00:54:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我的输入数据包含如下( 'label', ( 1.0, 2.0, 3.0 ) )的字符串,也包含如下( 'label', #75, #174, #196 )的字符串。前者可以使用ast.literal_eval()转换为元组,但后者失败,因为#xyz条目既不是数字也不是字符串。你知道吗

我想修改输入字符串,在每个#xyz条目周围加上引号,这样ast.literal_eval()就可以工作了,即( 'label', '#75', '#174', '#196' ),或者使用另一个函数,假设任何不是数字的东西都是字符串,不管是否加引号。你知道吗


Tags: 数据函数字符串eval条目数字astlabel
2条回答

您可以编写递归函数,从逗号之间的值构建元组,同时考虑括号分组:

例如:

s1 = "( 'label',  ( 1.0, 2.0, 3.0 ) )"
s2 = "( 'label', #75, #174, #196, 37 )"

def str2Tuple(s):
    if "(" not in s and "," not in s:
        try :   value = int(s) if s.isdigit() else float(s)
        except: value = s.strip("'")
        return value
    result      = []
    group,value = 0,""
    for c in s+",":
        if c == "," and group == 0:
            result.append(str2Tuple(value.strip()))
            value = "";continue
        group -= c==")"
        if group>0 or c not in "()": value += c
        group += c=="("
    return tuple(result) if len(result)>1 else result[0]

print(str2Tuple(s1)) # ('label', (1.0, 2.0, 3.0))
print(str2Tuple(s2)) # ('label', '#75', '#174', '#196', 37)                               

I would like to either modify the input string to place quotes around each #xyz entry so that ast.literal_eval() will work, i.e. ( 'label', '#75', '#174', '#196' )

使用re.sub将#N替换为引号内的数字:

>>> a = "( 'label', #75, #174, #196 )"
>>> a
"( 'label', #75, #174, #196 )"
>>> re.sub(r"#(\d+)", r"'#\1'", a)
"( 'label', '#75', '#174', '#196' )"

相关问题 更多 >