中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中JSON轉為Python可讀取的示例分析

發布時間:2022-03-04 10:33:02 來源:億速云 閱讀:154 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關JavaScript中JSON轉為Python可讀取的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

問題再現

數據是通過 JS 代碼傳遞的,大致格式(僅 作舉例說明 ,方便查看層次,實際 在同一行 )如下:

function (a, b, c, d){
    return {
        title: a,
        data: [
            {
            	data: b
        	},
            {
                data: c
            },
            {
                data: d
            }
    	]
    }
}('title', 2, 3, 4)

我要提取的是整個 JSON 格式的數據。

如果要直接提取,可以使用

re.findall('return (\{.*?\})\}\(', content)

得到結果,但如果要解析數據,會報以下的錯:

JavaScript中JSON轉為Python可讀取的示例分析

意思是:鍵值對中的鍵需要被雙引號包含

所以我們要完成任務的話,需要解決以下問題:

  • 鍵需要用 "" 包含。

  • 需要將形式參數 a, b, c, d 轉化為實際參數 "title", 2, 3, 4

解決辦法

形參與實參的對應關系容易解決,所以先解決這個問題。

形參與實參對應關系

可以使用以下代碼得到 形式參數

''.join(re.findall('function\((.*?)\)\{', content)).split(',')

使用下述代碼獲得 實際參數

''.join(re.findall('}\((.*?)\)', content)).split(',')

因為 形式參數實際參數個數 一樣,所以可以根據 列表索引 建立對應關系,使用 np.c_ 可以進行 列表橫向合并

代碼如下:

# 獲得實際參數Argument = ''.join(re.findall('}\((.*?)\)', content)).split(',')# 獲得形式參數Formal_parameter = ''.join(re.findall('function\((.*?)\)\{', content)).split(',')# 建立對應關系mapping = pd.DataFrame(np.c_[Formal_parameter, Argument])# 以形參作為索引mapping.set_index(0, drop=True, inplace=True)

結果如下:

JavaScript中JSON轉為Python可讀取的示例分析

格式化 JSON

要解決這個問題,我們需要先提取出 JSON 字符串,代碼如下:

string = ''.join(re.findall('return (\{.*?\})\}\(', content))

結果如下:

JavaScript中JSON轉為Python可讀取的示例分析

然后,我們需要有個思路,如下:

  • {, 后邊,: 之前的部分是 ,需要加上雙引號。

  • :[{ 后邊,], 之前的部分都是 ,需要識別且替換。

給鍵加上雙引號

因為涉及到 插入元素Python 中只有 列表 能擔此重任,所以我們需要先 將字符串轉為列表 ,代碼如下:

string = list(''.join(re.findall('return (\{.*?\})\}\(', content)))

然后,我們需要設置一個變量,當識別出是 的時候就 1 ,否則為 0

key_flag = 0

如果我們按照上文中的規則識別出 ,就要從當前位開始,一直到 : 之前的這部分都用 雙引號 包含。

還有些特殊情況,比如

  • 嵌套字典 ,比如一個列表中值均為字典 。

  • 空字典{ 后邊是 }

考慮到特殊情況,代碼如下:

index = 0

while True:
    # 如果索引超出范圍,就跳出循環
    if index >= len(string):
        break
    # 給鍵加雙引號
    if key_flag:
        # 在當前位插入一個雙引號
        string.insert(index, '"')
        index += 1
        # 循環讀取 
        while True:
            # 直到出現 ":",循環讀取的部分為 鍵
            # 在 鍵 的最后添加一個雙引號
            if string[index] == ':':
                string.insert(index, '"')
                # 重置 key_flag
                key_flag = 0
                # 終止循環
                break
            # 讀取下一位
            index += 1
    # 當前字符為 "{" 或 ",",則后邊的為 鍵
    if string[index] in '{,':
        key_flag = 1
        # 嵌套時,則將索引移向下一位
        if string[index+1] in '{':
            index += 1
        # 如果為空字典,則重置 key_value
        if string[index+1] in '}':
            key_flag = 0
    
    index += 1

結果如下(因篇幅限制,代碼無法截全):

JavaScript中JSON轉為Python可讀取的示例分析

可以看到,已經將所有的鍵用雙引號包含。

識別且替換值

這一部分還是小有難度的。

首先,和上邊一樣,我們還是需要一個變量,記錄當前識別 的狀態,1 代表識別出來了,0 代表沒有。

value_flag = 0

不過也是有特殊情況:

  • 值已經是字符串 ,但 字符串中有 :

  • 值是 js 語句 ,不過其不是我們要提取的數據。

考慮到特殊情況,代碼如下:

while True:
    
    if index >= len(string):
        break
    # 檢測到 值
    if value_flag:
        # 取出當前字符
        value = string.pop(index)
        # 如果字符是數字、"[" 和 "{" 或者已經是字符串
        if value in '"1234567890[{' or is_value:
            value_flag = 0
            string.insert(index, value)
            index += is_value
        # 不符合上述情況
        else:
            # 循環取出 值 字符串
            while True:
                # 如果為 "," 或 "}",則代表已取完
                if string[index] in ',}':
                    break
                value += string.pop(index)
            # 如果 值 字符串在對應關系中,就替換
            if value in mapping.index:
                # 因為是在當前位不斷插入,所以要將數據反向
                trans = mapping.loc[value][::-1]
            # 如果不在,則直接替換成空字符串
            else:
                trans = '""'
            # 計算索引要移動幾位
            length = len(trans)
            # 插入對應的數據
            for c in trans:
                string.insert(index, c)
            # 索引移動
            index += length
            
            value_flag = 0
            
            continue
    # 如果識別到 ":" 且該 ":" 不在值字符串中
    if string[index] in ':' and not is_value:
        value_flag = 1
        # 如果是值是字符串,則設置 is_value
        if string[index+1] in '"':
            is_value = 1
    # 識別值字符串結束,并重置 is_value
    elif string[index] in '"' and is_value:
        is_value = 0

    index += 1

結果如下:

JavaScript中JSON轉為Python可讀取的示例分析

可以看到,轉換的還是挺成功的。

總代碼

content = '''
function(a,b,c,d){return {title:a,data:[{data:b},{data:c},{data:d}]}}("title",2,3,4)
'''

string = list(''.join(re.findall('return (\{.*?\})\}\(', content)))

is_value = 0
key_flag = 0
value_flag = 0

index = 0

while True:
    
    if index >= len(string):
        break
    
    if key_flag:
        
        string.insert(index, '"')
        index += 1
        
        while True:
            if string[index] == ':':
                string.insert(index, '"')
                key_flag = 0
                break
            index += 1
            
    elif value_flag:
        
        value = string.pop(index)
        
        if value in '"1234567890[{' or is_value:
            value_flag = 0
            string.insert(index, value)
            index += is_value
        else:
            
            storage = index
            
            while True:
                if string[index] in ',}':
                    break
                value += string.pop(index)
            
            if value in mapping.index:
                trans = mapping.loc[value][::-1]
            else:
                trans = '""'
            length = len(trans)

            for c in trans:
                string.insert(index, c)

            index += length
            
            value_flag = 0
            
            continue
    
    if string[index] in '{,':
        key_flag = 1
        if string[index+1] in '{':
            index += 1
        if string[index+1] in '}':
            key_flag = 0

    elif string[index] in ':' and not is_value:
        value_flag = 1
        if string[index+1] in '"':
            is_value = 1
    
    elif string[index] in '"' and is_value:
        is_value = 0

    index += 1
    
''.join(string)

結果如下:

JavaScript中JSON轉為Python可讀取的示例分析

這時候就可以使用 json.loads 來提取數據了。

結果如下:

JavaScript中JSON轉為Python可讀取的示例分析

不足

其實上述代碼是有不足的地方的。因為這段 js 代碼是特殊的,是 在一行 ,且 沒有多余的空格

不過也是有解決辦法的:

如果 有空格 怎么辦? —> 在 提取形參使用形參轉換實參 時使用 strip 去除兩側的空格即可。

代碼不在一行 怎么辦? —> 使用 .replace('\t', '').replace('\n', '') 去除 換行符制表符 ,然后再進行格式化工作。

其實如果只是 代碼不在一行 的問題的話,js.loads 會幫我們去除 \n 之類的,直接提取重要部分。

不過如果要使用我的代碼的話,目前只支持 在一行js 代碼。

還有就是有些 將鍵值對的值設置成邏輯運算式 ,比如 a || "" 這種,也不太好提取,還得根據問題調整。

這些都只是思路,大家可以自行嘗試,如果有問題也及時提出來。

關于“JavaScript中JSON轉為Python可讀取的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淮北市| 巨鹿县| 凌海市| 通海县| 建水县| 荔浦县| 五大连池市| 南涧| 玛纳斯县| 犍为县| 铜山县| 兴业县| 昌江| 湖口县| 灵寿县| 朝阳县| 庆安县| 武宣县| 普洱| 陆川县| 南雄市| 金山区| 绍兴市| 平阴县| 石阡县| 临邑县| 吉木乃县| 凤冈县| 德兴市| 北票市| 呼和浩特市| 平湖市| 布尔津县| 湖口县| 嘉禾县| 汨罗市| 商河县| 延庆县| 宁远县| 汉阴县| 馆陶县|