0
votes

Traverser une chaîne de dictionnaire et magasin comme un seul dictionnaire à Python

J'ai une chaîne d'échantillonnage qui ressemble à un dictionnaire, mais contient une valeur qui comporte des citations doubles et une virgule qui rend difficile la lecture de Json.loads. Je répète le code pour trouver un élément et extraire sa valeur jusqu'à ce que "", "", "est trouvé et stockez-le comme une liste afin que les données puissent être converties en Dataframe.

Exemple: P>

{
    "_id": [
        "1231",
        "1245"
    ],
    "_address": [
        "akjd-dfdkfj",
        "sdsd-dgfg"
    ],
    "body": [
        "Your one time password is 'sdkd'. Enter this in the form to confirm your value.",
        "Dear Customer, Reference number is 3435.To check latest status, sms DROP DFGDG on 38388338. Thank you, ABC"
    ],
    "date": [
        "Thu May 10 23:34:11 GMT+05:30 2018",
        "Thu May 10 13:22:54 GMT+05:30 2018"
    ]
}


10 commentaires

Merci Jon, essayé cela avant et il dit une syntaxe invalide


Vous avez supprimé Triple citations à tort. Rapporte les.


Êtes-vous sûr que la chaîne source d'origine contient votre mot de passe unique est "SDKD". au lieu de Votre mot de passe unique est \ "sdkd \". ?


Oui, c'est le problème et ceci est présent dans un fichier TXT et ne peut pas être modifié à partir de la source d'origine. Cela provoque tout le problème pour analyser cette chaîne. De plus, il y a environ 25 millions de fichiers de ce type, vous ne pouvez donc pas les éditer manuellement.


@ user3222101 Les fichiers réels contiennent-ils de nouvelles lignes? Parce que la création d'une chaîne multiligne maintenant - je ne suis pas sûre de savoir si cela est à des fins de présentation pour nous faciliter la lecture, ou si vous avez vraiment des fichiers avec des lignes simples?


Oliver s'est formaté à un objectif de lisibilité Sinon, le texte est disponible en un exemple de format de ligne: {"" SMS ": [{" _ id ": ....} et je viens d'extraire du texte après SMS et l'enregistré dans filtré_data


@ user3222101, je n'ai aucune idée, quel logiciel peut produire une sortie JSON violant JSON STOCTARTS. Peut-être mieux de faire quelque chose avec l'entrée et ensuite simplement sérialiser Json?


Vous devriez mettre exactement même entrée (pas de nouvelles lignes ou avec de nouvelles lignes) dans la question, car cela dépend du format, le regex peut être très différent.


Qu'avez-vous dans le fichier après tout, \ "sdkd \" , "sdkd" ou 'sdkd' ?


@tevemadar: "SDKD"


4 Réponses :


1
votes

En supposant que les guillemets non échappés ne se produisent que dans "corporel" code> -lines, il peut être fixé dans un JSON approprié et analysé par la suite. Ensuite, vous avez une tâche de remodeler une liste de dictes dans une dict de listes.

import json,re

filtered_data = '''[
   {
      "_id":"1231",
      "address":"akjd-dfdkfj",
      "body":"Your one time password is "sdkd". Enter this in the form to confirm your value.",
      "date":"Thu May 10 23:34:11 GMT+05:30 2018"
   },
   {
      "_id":"1245",
      "address":"sdsd-dgfg",
      "body":"Dear Customer, Reference number is 3435.To check latest status, sms DROP DFGDG on 38388338. Thank you, ABC",
      "date":"Thu May 10 13:22:54 GMT+05:30 2018"
   }
]'''

corrected_data=re.sub("^\s*\"body\":\"(.*)\",",lambda x:"\"body\":\""+x.group(1).replace("\"","'")+"\",",filtered_data,flags=re.M)
dicts_in_list=json.loads(corrected_data)
lists_in_dict={key:[item[key] for item in dicts_in_list] for key in dicts_in_list[0].keys() }
print(lists_in_dict)


4 commentaires

Votre entrée diffère de l'entrée fournie en question.


@Olvinroght: Nope, il dit que les données proviennent d'un fichier, ce n'est qu'un exemple publié dans la question.


Non. Votre chaîne: mot de passe est \\ "sdkd \\". , original: mot de passe est "sdkd".


@Olvinroght: J'ai copié le texte de la question. Il contenait \ s à l'origine. Je vais demander...



0
votes

Si la chaîne formerait un document JSON valide, vous pouvez utiliser (vous avez probablement besoin d'ajouter '[' et ']' au début / fin de la chaîne:

result_dict= dict()
for res_dict in result_dicts:
    for key, value in res_dict.items():
        result_dict.setdefault(key, list()).append(value)


0 commentaires

0
votes

Une solution avec des expressions régulières ressemblerait à:

patt=re.compile('"([^"]*)"\s*:\s*"(.*?)"(,|\s*\})', re.MULTILINE)
result_dict=dict()
for key, value, sep in patt.findall(filtered_data):
    result_dict.setdefault(key, list()).append(value)


0 commentaires

0
votes

Ceci est une approche à l'aide de regex. Obtenez des valeurs à l'aide de lookahead & lookbehind

ex: xxx

Sortie: < / p> xxx


0 commentaires