La directiva require
es similar
en su funcionamiento al paréntesis 5.10 (??{ Código Perl })
el cuál hace que el Código Perl
sea evaluado durante el tiempo de matching.
El resultado de la evaluación se trata como una expresión regular con la que deberá
casarse.
(véase la sección 3.2.9
para mas detalles).
La sintáxis de la directiva <require:>
es
<require: (?{ CODE }) >
The code block is executed and if its final value is true, matching continues from the same position. If the block's final value is false, the match fails at that point and starts backtracking.
The <require:...>
directive is useful for testing conditions that it's
not easy (or even possible) to check within the syntax of the the regex
itself. For example:
<rule: IPV4_Octet_Decimal> # Up three digits... <MATCH= ( \d{1,3}+ )> # ...but less that 256... <require: (?{ $MATCH <= 255 })>
A require expects a regex codeblock as its argument and succeeds if the final value of that codeblock is true. If the final value is false, the directive fails and the rule starts backtracking.
Note, in this example that the digits are matched with\d{1,3}+
. The trailing+
prevents the{1,3}
repetition from backtracking to a smaller number of digits if the<require:...>
fails.
El programa demo_IP4.pl
ilustra el uso de la directiva:
pl@nereida:~/Lregexpgrammars/demo$ cat -n ./demo_IP4.pl 1 #!/usr//bin/env perl5.10.1 2 use v5.10; 3 use warnings; 4 5 use Regexp::Grammars; 6 7 my $grammar = qr{ 8 \A <IP4_addr> \Z 9 10 <token: quad> 11 <MATCH=(\d{1,3})> 12 <require: (?{ $MATCH < 256 })> 13 14 <token: IP4_addr> 15 <[MATCH=quad]>**(\.) 16 <require: (?{ @$MATCH == 4 })> 17 }xms; 18 19 while (my $line = <>) { 20 if ($line =~ $grammar) { 21 use Data::Dumper 'Dumper'; 22 say Dumper \%/; 23 } 24 else { 25 say 'Does not match' 26 } 27 }Las condiciones usadas en el
require
obligan a que cada
quad3.9 sea menor que 256 y a que existan sólo cuatro quads.
Sigue un ejemplo de ejecución:
pl@nereida:~/Lregexpgrammars/demo$ ./demo_IP4.pl 123 . 145 . 105 . 252 Does not match pl@nereida:~/Lregexpgrammars/demo$ ./demo_IP4.pl 123.145.105.252 $VAR1 = { '' => '123.145.105.252', 'IP4_addr' => [ 123, 145, 105, 252 ] }; pl@nereida:~/Lregexpgrammars/demo$ ./demo_IP4.pl 148.257.128.128 Does not match 0.0.0.299 Does not match pl@nereida:~/Lregexpgrammars/demo$ ./demo_IP4.pl 123.145.105.242.193 Does not matchObsérvese como no se aceptan blancos entre los puntos en esta versión. ¿Sabría explicar la causa?