[英]Python - Parsing JSON formatted text file with regex
我有一個格式類似於 JSON 文件的文本文件,但是所有內容都在一行中(可能是 MongoDB 文件)。 有人可以指出我如何使用 Python 正則表達式方法提取值的方向嗎?
文本顯示如下:
{"d":{"__type":"WikiFileNodeContent:http:\/\/samplesite.com.au\/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":
我想要獲取“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-0f24b59e1991
如何使用正向前瞻和后視:
(?<=\"fileAssetId\":\")[a-fA-F0-9-]+?(?=\")
捕獲fileAssetId
和
(?<=\"filename\":\").+?(?=\")
匹配文件名。
有關正則表達式的詳細說明,請查看Regex101 -Example。 (注意:我在示例中將兩者與 OR-Operator | 結合起來以同時顯示兩個匹配項)
要獲取所有匹配項的列表,請使用re.findall
或re.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.