2011-01-28 5 views
1

J'ai créé une expression rationnelle en Perl d'environ 95 caractères, je souhaite la raccourcir à 78 caractères mais je ne trouve pas de méthode appropriée. Tout accueil conseils, l'expression régulière est similaire au code ci-dessous, idéalement il y a quelque chose de similaire à \ en C.Raccourcissement RegEx pour Perl

my ($foo, $bar, $etc) = $input_line =~ 
/^\d+: .... (\X+)\(\X(\d+.\d+|\d+)\/\X(\d+.\d+|\d+) (\X+)\)$/ 
+3

* Pourquoi * voulez-vous raccourcir l'expression à * 78 * caractères? pourquoi pas 79 ou 77? – thkala

+0

Oh, et nous pourrions peut-être vous aider davantage si nous savions ce que l'expression (que, d'ailleurs, vous n'avez pas * posté *) est censée faire. – thkala

+0

@thkala - peut-être à cause d'un style de codage demandant aux lignes de ne pas contenir plus de 79 caractères (de préférence 78)? – eumiro

Répondre

0

Perl interpole regex, de sorte que vous pourriez faire quelque chose comme ça

my $input_line = '123: .... X(X1.1/X5 XXX)'; 

my $dOrI = '(\d+.\d+|\d+)'; 
my ($foo, $bar, $etc) = $input_line =~ 
/^\d+: .... (\X+)\(\X$dOrI\/\X$dOrI (\X+)\)$/; 

print "$foo, $bar, $etc"; 

sortie -.

X, 1.1, 5 
+0

Merci, cela fonctionnera très bien –

2

Il y a une façon de dire regex sauter des espaces intégrés et les commentaires, donc non seulement vous pouvez diviser Je le trouve en plusieurs lignes, mais je le commente aussi, le formate en sections, etc. Je pense que c'est «x», mais je n'ai pas de documentation à portée de main pour le moment, alors cherchez dans la page man.

Vous changeriez à quelque chose comme:

my ($foo, $bar, $etc) = $input_line =~/
     ^\d+: .... 
     (\X+)\(
      \X(\d+.\d+|\d+) # numerator 
      \/\X(\d+.\d+|\d+) # denominator 
      \ (\X+)\)$/x # mind the escaped space! 

Il est également possible de construire des pièces d'expression régulière séparément par le préfixe de chaîne « » et les qr combiner à l'aide de substitution variable. Quelque chose comme

my $num_re = qr/(\X+)\(\X(\d+.\d+|\d+)\/\X(\d+.\d+|\d+)/; 
my ($foo, $bar, $etc) = $input_line =~ /^\d+: .... $num_re (\X+)\)$/; 

Je n'ai pas fait cela depuis longtemps, donc je ne suis pas sûr de savoir si des drapeaux sont nécessaires.

+0

Yep. Le modificateur est 'x'. –

+0

C'est en effet/x. Lisez tout à ce sujet ici: http://perldoc.perl.org/perlre.html#Modifiers –

0

Une chose que je vois dans l'expression rationnelle est la période « \ d + \ d + '.

Vous savez que '.' dans une regex correspond à n'importe quel caractère, pas seulement un caractère de période réelle.

Si vous souhaitez spécifier uniquement un caractère de période réel, vous devrez utiliser '\.' au lieu.

L'autre chose est que vous pourriez être en mesure de remplacer '\ d + \ d + |. \ D +' avec '\ d + \ d +.?

[EDIT] une chose, si vous utilisez la interpolez regex plus d'une fois et ne le changez pas entre les utilisations, (disons, dans une boucle), vous devez utiliser l'option/o pour que Perl compile toute l'expression rationnelle afin qu'elle n'ait pas besoin d'être compilée à chaque fois.

+0

Merci, c'était en effet un bug dans mon code –