2009-05-11 3 views
3

Je suis en train d'analyser un fichier journal qui ressemble à ceci:correspondent à des modèles qui se chevauchent avec la capture en utilisant une expression régulière Matlab

%%%% 09-May-2009 04:10:29 
% Starting foo 
this is stuff 
to ignore 
%%%% 09-May-2009 04:10:50 
% Starting bar 
more stuff 
to ignore 
%%%% 09-May-2009 04:11:29 
... 

Cet extrait contient deux périodes de temps, je voudrais extraire, de la première délimiteur à la seconde, et de la seconde à la troisième. J'aimerais utiliser une expression régulière pour extraire les heures de début et de fin de chacun de ces intervalles. Cela fonctionne la plupart du temps:

p = '%{4} (?<start>.*?)\n% Starting (?<name>.*?)\n.*?%{4} (?<stop>.*?)\n'; 
times = regexp(c,p,'names'); 

retour:

times = 

1x16 struct array with fields: 
    start 
    name 
    stop 

Le problème est que ce ne capture que tous les temps, depuis le deuxième delimiter est consommé dans le cadre du premier match. Dans d'autres langues, vous pouvez utiliser des opérateurs de lookaround (lookahead, lookbehind) pour résoudre ce problème. Le documentation on regular expressions explique comment cela fonctionne dans MATLAB, mais je n'ai pas réussi à les faire fonctionner tout en capturant les matchs. C'est-à-dire que je dois non seulement être capable de faire correspondre chaque délimiteur, mais aussi que j'ai besoin d'extraire une partie de cette correspondance (l'horodatage).

Est-ce possible?

P.S. Je me rends compte que je peux résoudre ce problème en écrivant une machine d'état simple ou en faisant correspondre les délimiteurs et le post-traitement, s'il n'y a aucun moyen de faire fonctionner cela.

Mise à jour: Merci pour les idées de contournement, tout le monde. J'ai entendu parler du développeur et il n'y a actuellement aucun moyen de le faire avec le moteur d'expressions régulières dans MATLAB.

+0

À quoi ressemblera la dernière ligne du fichier journal? Est-ce que ce sera une ligne "%%%% ..." sans rien après, ou est-ce qu'elle se termine par les choses précédentes à ignorer? – gnovice

+0

Toutes les lignes de délimitation se ressemblent, donc la dernière inclut un horodatage et vous permet de savoir quand la dernière période s'est terminée. Il y a des lignes supplémentaires à ignorer après le dernier délimiteur. –

Répondre

2

semble incapable de Matlab saisir les caractères comme un jeton sans les retirer de la chaîne (ou, devrais-je dire, je n'a pas pu le faire en utilisant Matlab REGEXP). Cependant, en notant que le temps d'arrêt pour un bloc de texte est égal à l'heure de début du suivant, j'ai pu capturer seulement les heures de début et les noms en utilisant REGEXP, puis effectuer un traitement simple pour obtenir les temps d'arrêt du heures de début. J'ai utilisé le texte exemple suivant:

c = 

%%%% 09-May-2009 04:10:29 
% Starting foo 
this is stuff 
to ignore 
%%%% 09-May-2009 04:10:50 
% Starting bar 
more stuff 
to ignore 
%%%% 09-May-2009 04:11:29 
some more junk 

... et appliqué l'expression suivante:

p = '%{4} (?<start>[^\n]*)\n% Starting (?<name>[^\n]*)[^%]*|%{4} (?<start>[^\n]*).*'; 

Le traitement peut alors être fait avec le code suivant:

names = regexp(c,p,'names'); 
[names.stop] = deal(names(2:end).start,[]); 
names = names(1:end-1); 

.. .qui nous donne ces résultats pour l'exemple de texte ci-dessus:

>> names(1) 

ans = 

    start: '09-May-2009 04:10:29' 
    name: 'foo' 
    stop: '09-May-2009 04:10:50' 

>> names(2) 

ans = 

    start: '09-May-2009 04:10:50' 
    name: 'bar' 
    stop: '09-May-2009 04:11:29' 
+0

J'ai corrigé l'anti-causalité du log. Ceux-ci étaient censés être séquentiels. –

0

Tout ce que vous devriez avoir à faire est d'envelopper une préanalyse autour de la partie de l'expression régulière qui correspond à la deuxième horodatage:

'%{4} (?<start>.*?)\n% Starting (?<name>.*?)\n.*?(?=%{4} (?<stop>.*?)\n)' 

EDIT: Ici, il est sans groupes nommés:

'%{4} (.*?)\n% Starting (.*?)\n.*?(?=%{4} (.*?)\n)' 
+0

Alan, merci d'avoir essayé. Lorsque j'essaie ce que vous suggérez (et ajoute le paren de fermeture), il capture plus les valeurs. –

+0

Essayez-le sans groupes nommés, alors. Dans toutes les autres saveurs regex que je connais et qui supportent les lookaheads et les groupes de capture, vous pouvez capturer des choses à l'intérieur d'un lookahead. Mais il se peut que MATLAB ne le permette pas. –

+0

Même sans utiliser de groupes nommés, cela ne semble toujours pas fonctionner. Je pense que MATLAB a du mal à résoudre simultanément les opérations de jetons/groupements et les opérations d'anticipation. – gnovice

1

Si vous font beaucoup d'analyse et un tel travail, vous pourriez envisager d'utiliser Perl from within Matlab. Il vous donne accès au puissant moteur de regex de Perl et peut également faciliter la résolution de nombreux autres problèmes.

Questions connexes