簡體   English   中英

模式匹配從字符串中獲取列表和字典

[英]pattern match get list and dict from string

我在下面有字符串,我想從這個字符串中獲取列表、字典、變量。 如何將此字符串拆分為特定格式?

s = 'list_c=[1,2],a=3,b=1.3,c=abch,list_a=[1,2],dict_a={a:2,b:3}'

import re
m1 = re.findall (r'(?=.*,)(.*?=\[.+?\],?)',s)
for i in m1 :
    print('m1:',i)

我只能正確得到結果 1。 有誰知道該怎么做?

m1: list_c=[1,2],
m1: a=3,b=1.3,c=abch,list_a=[1,2],

改用“=”進行拆分,然后您可以使用變量名及其值。

您仍然需要處理值的類型轉換( regexsplit嘗試使用轉換可能會有所幫助)。

另外,和其他人的評論一樣,使用 dict 可能更容易處理

s = 'list_c=[1,2],a=3,b=1.3,c=abch,list_a=[1,2],dict_a={a:2,b:3}'
al = s.split('=')
var_l = [al[0]]
value_l = []

for a in al[1:-1]:
  var_l.append(a.split(',')[-1])
  value_l.append(','.join(a.split(',')[:-1]))
value_l.append(al[-1])

output = dict(zip(var_l, value_l))
print(output)

如果您或多或少地明確描述右側表達式:數字、列表、字典和標識符,您可能會有更好的運氣:

re.findall(r"([^=]+)=" # LHS and assignment operator
                  +r"([+-]?\d+(?:\.\d+)?|" # Numbers
                  +r"[+-]?\d+\.|" # More numbers
                  +r"\[[^]]+\]|" # Lists
                  +r"{[^}]+}|" # Dictionaries
                  +r"[a-zA-Z_][a-zA-Z_\d]*)", # Idents
           s)
# [('list_c', '[1,2]'), ('a', '3'), ('b', '1.3'), ('c', 'abch'), 
#  ('list_a', '[1,2]'), ('dict_a', '{a:2,b:3}')]

答案如下

import re
from pprint import pprint
s = 'list_c=[1,2],a=3,b=1.3,c=abch,list_a=[1],Save,Record,dict_a={a:2,b:3}'
m1 = re.findall(r"([^=]+)=" # LHS and assignment operator
                  +r"([+-]?\d+(?:\.\d+)?|" # Numbers
                  +r"[+-]?\d+\.|" # More numbers
                  +r"\[[^]]+\]|" # Lists
                  +r"{[^}]+}|" # Dictionaries
                  +r"[a-zA-Z_][a-zA-Z_\d]*)", # Idents
           s)
temp_d = {}
for i,j in m1:    
    temp = i.strip(',').split(',')       
    if len(temp)>1:
        for k in temp[:-1]:
            temp_d[k]=''
        temp_d[temp[-1]] = j
    else:
        temp_d[temp[0]] = j
pprint(temp_d)

Output 就像

{'Record': '',
 'Save': '',
 'a': '3',
 'b': '1.3',
 'c': 'abch',
 'dict_a': '{a:2,b:3}',
 'list_a': '[1]',
 'list_c': '[1,2]'}

您可以從捕獲標識符開始,而不是挑選類型。 這是一個捕獲字符串中所有標識符的正則表達式(僅適用於小寫,但請參閱注釋):

regex = re.compile(r'([a-z]|_)+=')
#note if you want all valid variable names: r'([a-z]|[A-Z]|[0-9]|_)+'
cases = [x.group() for x in re.finditer(regex, s)]

這給出了字符串中所有標識符的列表:

['list_c=', 'a=', 'b=', 'c=', 'list_a=', 'dict_a=']

我們現在可以定義一個 function 來順序切分s使用上面的列表來按順序划分字符串:

def chop(mystr, mylist):
    temp = mystr.partition(mylist[0])[2]
    cut = temp.find(mylist[1])           #strip leading bits
    return mystr.partition(mylist[0])[2][cut:], mylist[1:]
mystr = s[:]
temp = [mystr]
mylist = cases[:]
while len() > 1:
    mystr, mylist = chop(mystr, mylist)
    temp.append(mystr)

這個(復雜的)切片操作給出了這個字符串列表:

['list_c=[1,2],a=3,b=1.3,c=abch,list_a=[1,2],dict_a={a:2,b:3}',
'a=3,b=1.3,c=abch,list_a=[1,2],dict_a={a:2,b:3}',         
'b=1.3,c=abch,list_a=[1,2],dict_a={a:2,b:3}',
'c=abch,list_a=[1,2],dict_a={a:2,b:3}',
'list_a=[1,2],dict_a={a:2,b:3}',
'dict_a={a:2,b:3}'] 

現在使用每個連續的條目切斷末端:

result = []
for x in range(len(temp) - 1):
    cut = temp[x].find(temp[x+1]) - 1    #-1 to remove commas
    result.append(temp[x][:cut])
result.append(temp.pop())                #get the last item

現在我們有了完整的列表:

['list_c=[1,2]', 'a=3', 'b=1.3', 'c=abch', 'list_a=[1,2]', 'dict_a={a:2,b:3}']

每個元素都可以輕松解析為鍵:值對(也可以通過exec )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM