Fußangel in Perl
Tuesday, July 26, 2011 8:08:55 AM
Ein Problem, wenn beim Suchen und Ersetzen der Suchstring runde Klammern enthält, und die Lösung.
Eigentlich ganz einfach, ich habe zwei verschiedene Zeichenketten und möchte jeweils den Teil ab "a Camel" ersetzen. Mal klappt die Ersetzung, mal nicht. (Ich weiß, es geht in diesem Fall auch einfacher.)
#! /usr/bin/perl
use strict;
use warnings;
use diagnostics;
my $EasyString = 'A string with a Camel Cigarette.';
my $ProblemString = 'A string with a Camel (Camelus bactrianus)!';
my @String = ($EasyString, $ProblemString, $EasyString, $ProblemString);
foreach my $string (@String)
{
if ($string =~ /(a Camel.*).$/)
{
my $CamelPart = $1;
$string =~ s/$CamelPart/some Camel/;
}
print $string, "\n";
}
Das Ergebnis:
A string with some Camel. A string with a Camel (Camelus bactrianus)! A string with some Camel. A string with a Camel (Camelus bactrianus)!Das Problem:
Sobald runde Klammern auf der linken Seite im Suchausdruck (s/Suchausdruck/Ersetzausdruck/) stehen, denkt perl, man möchte damit einen Teil aus dem Suchausdruck herausziehen und später mit $1 wiederverwenden. In der Zeile
if ($string =~ /(a Camel.*).$/)wollte ich das tatsächlich. Aber in der Zeile
$string =~ s/$CamelPart/some Camel/;nicht, weil dann mein Suchausdruck nicht mehr passt. Perl sucht in diesem Fall nach "a Camel Camelus bactrianus", also ohne Klammern, und findet es nicht.
Die Lösung:
$string =~ s/\Q$CamelPart\E/some Camel/xms;Zwischen \Q und \E werden alle Such-Sonderzeichen ignoriert, z.B.
. [ ] ( ) \s \netc. Damit werden auch die runden Klammern im Such-String nicht mehr als Sonderzeichen, sondern als normale Klammern interpretiert.
#! /usr/bin/perl
use strict;
use warnings;
use diagnostics;
my $EasyString = 'A string with a Camel Cigarette';
my $ProblemString = 'A string with a Camel (Camelus bactrianus)';
my @String = ($EasyString, $ProblemString, $EasyString, $ProblemString);
foreach my $string (@String)
{
if ($string =~ /(a Camel.*)/)
{
my $CamelPart = $1;
$string =~ s/\Q$CamelPart\E/some Camel/xms;
}
print $string, "\n";
}
Ergebnis:A string with some Camel. A string with some Camel! A string with some Camel. A string with some Camel!
Alles ist gut.
PS: Dank an Wolfgang für den Hinweis auf \Q \E.


Unregistered user # Tuesday, July 26, 2011 8:41:35 AM
SaschaEinSascha # Tuesday, July 26, 2011 11:40:54 AM