1
votes

Expression régulière pour faire correspondre des groupes qui peuvent ne pas exister

J'essaie de capturer des données à partir des journaux d'une application. Les journaux ressemblent à ceci:

^[^=\n]*=(?:(?P<STATE1>\d+)(?=\.0,\s+\w+=STATE1))*.*?=(?P<STATE2>\d+)(?=\.0,\s+\w+=STATE2)*.*?=(?P<STATE3>\d+)(?=\.0,\s+\w+=STATE3)

Si le count pour un état particulier est égal à 0, il ne sera en fait pas du tout dans le journal, donc je peux ne garantit pas l'ordre des objets dans le journal (le seul ordre est qu'ils sont triés par ordre alphabétique par nom d'état)

Donc, c'est aussi un journal potentiel: p>

*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*

Je suis un peu nouveau dans l'utilisation des expressions régulières, et je pense que j'en fais trop, mais c'est ce que j'ai essayé.

*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE2}, {count=93.0, state=STATE3}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*


3 commentaires

Ce n'est pas JSON ( = au lieu de : pour un). C'est une bonne recommandation s'il s'agit d'un format quelconque, si vous pouvez déterminer quel type.


Oui, je viens de remarquer que ... Vous pouvez facilement utiliser regex pour capturer les informations de comptage / état, puis filtrer plus loin. Je n'essaierais tout simplement pas de tout faire dans RegEx.


Personnellement, je séparerais l'ivraie du blé et n'opérerais que sur le contenu que vous souhaitez interpréter. Deux étapes, supprimez les fichiers indésirables, faites correspondre ou consommez des données. Faire les deux dans la même étape semble trop compliqué, sans voir ce qu'est réellement l'ordure.


3 Réponses :


1
votes

Vérifiez si cette approche fonctionne pour vous:

Regex: (? <= count =) \ d + (?: \. \ d +)? (? =, state = (STATE \ d +))

Démo

Le groupe sera votre numéro d'état et la correspondance complète sera la valeur de comptage


0 commentaires

1
votes

Vous pouvez utiliser 2 groupes de capture pour capturer le décompte et l'état.

Pour capturer par exemple STATE1, STATE2, STATE3 et STATE5, vous pouvez spécifier les nombres en utilisant une classe de caractères avec des plages et / ou une alternance.

{count=(\d+(?:\.\d+)?), state=(STATE\d+)}

Explication

  • {count = Correspondre littéralement
  • ( Capturer le groupe 1
    • \ d + (?: \. \ d +)? Faire correspondre 1+ chiffres avec une partie décimale facultative
  • ) Fermer le groupe
  • , state = Correspondre littéralement
  • ( Capturer le groupe 2
    • STATE (?: [123] | 5) Faites correspondre STATE et spécifiez les nombres autorisés
  • )} Fermer le groupe et faire correspondre }

Démo Regex


Si vous voulez faire correspondre tous les états et chiffres:

{count=(\d+(?:\.\d+)?), state=(STATE(?:[123]|5))}

Démo Regex


0 commentaires

0
votes

Après quelques expérimentations, voici ce que j'ai trouvé:

Les réponses fournies ici, bien que bonnes réponses em> , ne fonctionne pas tout à fait si vos noms d'état ne se terminent pas par un chiffre ( le mien ne le fait pas, je les ai simplement modifiés pour rendre la question plus facile à lire et pour supprimer les informations commerciales de la question ).

Voici une regex complètement tuile où vous pouvez ajouter autant de correspondances que nécessaire

[{count=55.0, state=STATE_ONE}, {count=10.0, state=STATE_THREE}]

Cela peut être copié et ajouté avec le nouveau nom d'état et le nom du groupe. En outre, si l'un des états n'apparaît pas dans la chaîne, il correspondra toujours aux états suivants. Par exemple:

count=(?P<G1>\d+(?=\.0, state=STATE_ONE))?(?P<G2>\d+(?=\.0, state=STATE_TWO))?(?P<G3>\d+(?=\.0, state=STATE_THREE))?

fera correspondre les états STATE_ONE et STATE_THREE avec les groupes nommés G1 & G3 dans la chaîne suivante même si STATE_TWO est manquant:

count=(?P<GROUP_NAME_HERE>\d+(?=\.0, state=STATE_NAME_HERE))?

Je suis sûr que cela pourrait être amélioré, mais c'est assez rapide pour moi, et avec 11 groupes , regex101 montre 803 pas avec un temps de ~1ms

Voici un terrain de jeu regex101 pour jouer avec: https://regex101.com/r/3a3iQf/1

Remarquez comment les groupes 1, 2, 3, 4, 5, 6, 7, 9 et 11 correspondent. 8 et 10 sont manquants et les groupes suivants correspondent toujours.


1 commentaires

Je vois que vous avez fourni votre propre réponse. Notez que (?: Count =) peut être écrit comme count =