Perl Language
Normale uitdrukkingen
Zoeken…
Bijpassende snaren
De operator =~
probeert een reguliere expressie (apart gezet door /
) te koppelen aan een tekenreeks:
my $str = "hello world";
print "Hi, yourself!\n" if $str =~ /^hello/;
/^hello/
is de werkelijke reguliere expressie. De ^
is een speciaal teken dat de reguliere expressie vertelt om te beginnen met het begin van de tekenreeks en niet ergens in het midden te matchen. Vervolgens probeert de regex de volgende letters te vinden in volgorde h
, e
, l
, l
en o
.
Reguliere expressies proberen overeen te komen met de standaardvariabele ( $_
) als deze kaal zijn:
$_ = "hello world";
print "Ahoy!\n" if /^hello/;
U kunt ook verschillende scheidingstekens gebruiken als u de reguliere expressie voorafgaat met de operator m
:
m~^hello~;
m{^hello};
m|^hello|;
Dit is handig bij het matchen van tekenreeksen die het /
-teken bevatten:
print "user directory" if m|^/usr|;
Gebruik van \ Q en \ E in patroonovereenkomst
Wat tussen \ Q en \ E staat, wordt als normale tekens behandeld
#!/usr/bin/perl
my $str = "hello.it's.me";
my @test = (
"hello.it's.me",
"hello/it's!me",
);
sub ismatched($) { $_[0] ? "MATCHED!" : "DID NOT MATCH!" }
my @match = (
[ general_match=> sub { ismatched /$str/ } ],
[ qe_match => sub { ismatched /\Q$str\E/ } ],
);
for (@test) {
print "\String = '$_':\n";
foreach my $method (@match) {
my($name,$match) = @$method;
print " - $name: ", $match->(), "\n";
}
}
uitgang
String = 'hello.it's.me': - general_match: MATCHED! - qe_match: MATCHED! String = 'hello/it's!me': - general_match: MATCHED! - qe_match: DID NOT MATCH!
Een string parseren met een regex
Over het algemeen is het geen goed idee om een reguliere expressie te gebruiken om een complexe structuur te parseren . Maar het kan wel. U wilt bijvoorbeeld gegevens in de componenttabel laden en velden worden gescheiden door komma's, maar complexe typen zoals array worden gescheiden door een "|". Bestanden bevatten records met alle velden gescheiden door komma en complex type staan tussen vierkante haakjes. In dat geval kan dit beetje wegwerpperl voldoende zijn:
echo "1,2,[3,4,5],5,6,[7,8],[1,2,34],5" | \
perl -ne \
'while( /\[[^,\]]+\,.*\]/ ){
if( /\[([^\]\|]+)\]/){
$text = $1;
$text_to_replace = $text;
$text =~ s/\,/\|/g;
s/$text_to_replace/$text/;
}
} print'
U wilt de uitvoer ter plaatse controleren:
1,2, [3 | 4 | 5], 5,6 [7 | 8], [1 | 2 | 34], 5
Vervang een string met reguliere expressies
s/foo/bar/; # replace "foo" with "bar" in $_
my $foo = "foo";
$foo =~ s/foo/bar/; # do the above on a different variable using the binding operator =~
s~ foo ~ bar ~; # using ~ as a delimiter
$foo = s/foo/bar/r; # non-destructive r flag: returns the replacement string without modifying the variable it's bound to
s/foo/bar/g; # replace all instances