簡體   English   中英

Python - 使用正則表達式解析 JSON 格式的文本文件

[英]Python - Parsing JSON formatted text file with regex

我有一個格式類似於 JSON 文件的文本文件,但是所有內容都在一行中(可能是 MongoDB 文件)。 有人可以指出我如何使用 Python 正則表達式方法提取值的方向嗎?

文本顯示如下:

{"d":{"__type":"WikiFileNodeContent:http:\/\/samplesite.com.‌​au\/ns\/business\/wi‌​ki","author":null,"d‌​escription":null,"fi‌​leAssetId":"034b9317‌​-60d9-45c2-b6d6-0f24‌​b59e1991","filename"‌​:"Reports.pdf"},"cre‌​atedBy":1531,"create‌​dByUsername":"John Cash","icon":"\/Assets10.37.5.0\/pix\/16x16\/page_white_acro‌​bat.png","id":3041,"‌​inheritedPermissions‌​":false,"name":"map"‌​,"permissions":[23,8‌​7,35,49,65],"type":3‌​,"viewLevel":2},{"__‌​type":"WikiNode:http‌​:\/\/samplesite.com.‌​au\/ns\/business\/wi‌​ki","children":[],"c‌​ontent": 

我想要獲取“fileAssetId”和文件名“。我嘗試使用 Pythons JSON 模塊加載類似的內容,但出現錯誤

對於 FileAssetid 我嘗試了這個正則表達式:

regex = re.compile(r"([0-9a-f]{8})\S*-\S*([0-9a-f]{4})\S*-\S*([0-9a-f]{4})\S*-\S*([0-9a-f]{4})\S*-\S*([0-9a-f]{12})")

但我得到以下 034b9317‌ , 60d9, 45c2, b6d6, 0f24‌ b59e1991

我不確定如何獲取顯示的數據。

您可以使用 python 的walk 方法並使用re.match檢查每個條目。

如果你得到的字符串不能轉換為 python dict,你可以只使用正則表達式:

print re.match(r'.*fileAssetId\":\"([^\"]+)\".*', your_pattern).group(1)

您的示例的解決方案:

import re

example_string = '{"d":{"__type":"WikiFileNodeContent:http:\/\/samplesite.com.u\/ns\/business\/wiki","author":null,"description":null,"fileAssetId":"034b9317-60d9-45c2-b6d6-0f24b59e1991","filename":"Reports.pdf"},"createdBy":1531,"createdByUsername":"John Cash","icon":"\/Assets10.37.5.0\/pix\/16x16\/page_white_acrobat.png","id":3041,"inheritedPermissions":false,"name":"map","permissions":[23,87,35,49,65],"type":3,"viewLevel":2},{"__type":"WikiNode:http:\/\/samplesite.com.au\/ns\/business\/wiki","children":[],"content"'

regex_pattern = r'.*fileAssetId\":\"([^\"]+)\".*'
match = re.match(regex_pattern, example_string)
fileAssetId = match.group(1)
print('fileAssetId: {}'.format(fileAssetId))

執行這個產生:

34b9317‌​-60d9-45c2-b6d6-0f24‌​b59e1991

如何使用正向前瞻和后視:

(?<=\"fileAssetId\":\")[a-fA-F0-9-]+?(?=\")

捕獲fileAssetId

(?<=\"filename\":\").+?(?=\")

匹配文件名。

有關正則表達式的詳細說明,請查看Regex101 -Example。 (注意:我在示例中將兩者與 OR-Operator | 結合起來以同時顯示兩個匹配項)

要獲取所有匹配項的列表,請使用re.findallre.finditer而不是re.match

re.findall(pattern, string)返回匹配字符串的列表。

re.finditer(pattern, string)返回一個帶有對象的迭代器。

嘗試將 \\n 添加到您輸入到文件中的字符串中(\\n 表示換行)

基於此處給出的想法https://stackoverflow.com/a/3845829並遵循 JSON 標准https://www.json.org/json-en.html ,我們可以使用 Python + regex https://pypi .org/project/regex/並執行以下操作:

json_pattern = (
    r'(?(DEFINE)'
    r'(?P<whitespace>( |\n|\r|\t)*)'
    r'(?P<boolean>true|false)'
    r'(?P<number>-?(0|([1-9]\d*))(\.\d*[1-9])?([eE][+-]?\d+)?)'
    r'(?P<string>"([^"\\]|\\("|\\|/|b|f|n|r|t|u[0-9a-fA-F]{4}))*")'
    r'(?P<array>\[((?&whitespace)|(?&value)(,(?&value))*)\])'
    r'(?P<key>(?&whitespace)(?&string)(?&whitespace))'
    r'(?P<value>(?&whitespace)((?&boolean)|(?&number)|(?&string)|(?&array)|(? &object)|null)(?&whitespace))'
    r'(?P<object>\{((?&whitespace)|(?&key):(?&value)(,(?&key):(?&value))*)\})'
    r'(?P<document>(?&object)|(?&array))'
    r')'
    r'(?&document)'
)

json_regex = regex.compile(json_pattern)

match = json_regex.match(json_document_text)

您可以更改json_pattern最后一行以匹配不是文檔而是單個對象替換(?&document)(?&object) 我認為正則表達式比我預期的要容易,但我沒有對此進行廣泛的測試。 它對我來說很好用,我已經測試了數百個文件。 如果我在運行時發現任何問題,我將嘗試改進我的答案。

暫無
暫無

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

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