2
votes

Groupes de capture Perl avec journaux utilisant des expressions régulières

J'essaye de convertir cette ligne de journal:

2019-02-25 00:39:01,[]
2019-02-25 00:50:06,[]
2019-02-25 03:59:42,[]

en une feuille de calcul qui ressemble à ceci:

perl -ne 'print "$1,$2\n" if /\[(.*?)\].+(\[.*\])/' filename

J'ai essayé d'écrire cette ligne

|       time          |   phone number   |            sms job id          | 
---------------------------------------------------------------------------
| 2019-02-25 00:39:01 | +96605992911111  |000000001328e347000000003113b4f8|
| 2019-02-25 00:50:06 | +96605992911112  |00000000206561fd000000003fb01b05|
| 2019-02-25 03:59:42 | +96605992911113  |0000000003baa9660000000022c0679c|

mais tout ce que j'ai est ceci:

9:[2019-02-25 00:39:01] production.DEBUG: JOB-VARS : {"phone_numbers":["+9660599291111"],"message":"Your verification code is: 74222","twilio":{},"objectKey":"job:class:App\\Jobs\\SmsJob:000000001328e347000000003113b4f8","connection":"sqs-high","queue":null,"delay":null,"job":{},"JOB-CLASS":"App\\Jobs\\SmsJob"} [] []
16:[2019-02-25 00:50:06] production.DEBUG: JOB-VARS : {"phone_numbers":["+9660533001112"],"message":"Your verification code is: 31231","twilio":{},"objectKey":"job:class:App\\Jobs\\SmsJob:00000000206561fd000000003fb01b05","connection":"sqs-high","queue":null,"delay":null,"job":{},"JOB-CLASS":"App\\Jobs\\SmsJob"} [] []
54:[2019-02-25 03:59:42] production.DEBUG: JOB-VARS : {"phone_numbers":["+9647707771113"],"message":"Your verification code is: 64628","twilio":{},"objectKey":"job:class:App\\Jobs\\SmsJob:0000000003baa9660000000022c0679c","connection":"sqs-high","queue":null,"delay":null,"job":{},"JOB-CLASS":"App\\Jobs\\SmsJob"} [] []

Je suis resté coincé en capturant le deuxième groupe. Des idées?


9 commentaires

Essayez ceci


En exécutant la même commande perl sur ce fichier, j'obtiens des résultats différents mais attendus. Êtes-vous sûr que la chaîne d'entrée est la même que celle que vous avez publiée?


@revo désolé j'ai supprimé des fichiers indésirables, le fichier journal réel ressemble à ceci


@Potato .. ça a marché comme un charme!


Remarque - vous capturez et imprimez deux choses, alors que trois sont nécessaires? De plus, je suppose que les données affichées sont correctes (et qu'un peu plus qu'il y en a sur chaque ligne, comme on le voit sur le lien donné ci-dessus, est exactement comme vu dans ce lien, n'affectant pas les modèles)


Le deuxième modèle de votre expression régulière correspond au [] vide à la fin de la ligne (vu dans le lien, pas dans la question) en raison de la gourmandise de . +


question mise à jour pour inclure les journaux réels pour éviter toute confusion


cela a parfaitement fonctionné! je t'ai accordé la bonne réponse


Génial, bon d'entendre tout est bon :) Et merci de vous en être occupé.


4 Réponses :


1
votes

Vous pouvez essayer ce modèle \ [([^ \]] ++) \]. + phone \ _numbers \ D ++ (\ d ++). + SmsJob \: (\ w ++)

Explication:

\ [([^ \]] ++) \] correspondra à la date entre crochets, capturant la date dans un groupe,

. + phone \ _numbers \ D ++ (\ d ++) correspondra à un ou plusieurs de tous les caractères, puis phone_number littéralement, puis un ou plusieurs non-chiffres, puis il capturera le numéro de téléphone réel dans un groupe avec (\d++)

. + SmsJob \: (\ w ++) correspondra d'abord à un ou plusieurs caractères, puis SmsmJob littéralement, puis : et puis capturera l'ID de la tâche dans un autre groupe de capture


0 commentaires

2
votes

Se fier entièrement aux détails du format, avec tous les " et [] etc

perl -wnE'
    say "$1, $2, $3"  
        if /:\[(.*?)\].*?"phone_numbers":\["(.*?)"\].*?SmsJob:(.*?)"/
' file

où j'utilise des phrases explicites (comme "phone_numbers": ) pour ancrer les modèles nécessaires.

Notez les modèles non gourmands partout. Puisque nous avons des "ancres" textuelles pratiques pour ce que nous devons capturer, il n'y a aucune raison pour laisser les schémas gourmands se déchaîner; ils sont beaucoup plus difficiles à suivre mentalement, peuvent être difficiles à obtenir et sont généralement moins efficaces.

Notez que j'utilise " après SmsJob car SmsJob: vient en dernier dans objectKey et il se trouve que " a raison après, ce qui est pratique pour délimiter le motif à correspondre. Mais si ce " n'est pas certain d'être là, alors . *? doit être changé; peut-être à [0-9a-zA-Z] (modèle minimal pour ce qui est autorisé dans la valeur SmsJob ), suivi d'un caractère littéral qui le termine (comme , ou : etc).

Ceci capture correctement l'horodatage et le numéro de téléphone et SmsJob à partir de l'échantillon donné.


† Le deuxième modèle de la tentative honnête de la question ne parvient pas à capturer ce qui est attendu car le gourmand . + saisit tout jusqu'au bout dernière paire [] dans la chaîne, puisque le \ [. * \] qui vient après . + correspond à ce dernier [ ] donc tout le motif correspond de cette façon.


0 commentaires

1
votes

Votre regex actuelle est tellement gourmande et la chaîne d'entrée donnée est sûrement différente. Vous n'avez pas non plus essayé d'obtenir trois groupes de capture. Essayez plutôt ceci:

perl -ne 'print "$1,$2,$3\n" if /\[([\d: -]+)\][^][]+\["([^][]+)"\].*?SmsJob:(\w+)/' filename

Perl:

\[([\d: -]+)\][^][]+\["([^][]+)"\].*?SmsJob:(\w+)

Répartition des expressions régulières:

  • \ [ Match [ littéralement
  • ( Début du premier groupe de capture
    • [\ d: -] + Correspond à une combinaison de caractères spécifiés (chiffre, : , espace et - )
  • ) Fin du groupe de capture
  • \] Match ] littéralement
  • [^] [] + Correspond à tout sauf à [ et
  • \ [" Match [" littéralement
  • ( Début du deuxième groupe de capture
    • [^] [] + Correspond à tout sauf à [ et
  • ) Fin du groupe de capture
  • "\]. *? SmsJob: Correspond à SmsJob:
  • (\ w +) Faire correspondre une séquence de caractères de mots et stocker dans le 3ème groupe de capture


0 commentaires

0
votes

Pour moi, votre "JOB-VARS" ressemble beaucoup à JSON. Envisagez peut-être d'utiliser le module JSON.

use strict;
use warnings;
use JSON;
my $json= new JSON;
while (<>) {
    my ($ts, $jtext)= /\[(.*?)\] production.DEBUG: JOB-VARS : (.*)/;
    my ($obj)= $json->decode_prefix($jtext);
    my $phone_number= $obj->{phone_numbers}->[0];
    my $jid= $obj->{objectKey};
    $jid=~ s/^.*://;
    printf "| %19s | %-15s |%32s|\n",$ts,$phone_number,$jid;
}


0 commentaires