• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[solved] s/?eins/zwei/ gibt Fehler in Perl

framp

Moderator
Teammitglied
Code:
perl -e '$_="eins";s/eins/zwei/;print "$_\n"'
liefert wie gewünscht das Ergebnis.
Code:
perl -e '$_="?eins";s/?eins/zwei/;print "$_\n"'
liefert die Fehlermeldung
Code:
Quantifier follows nothing in regex; marked by <-- HERE in m/? <-- HERE eins/ at -e line 1.
Hat jemand eine Idee wie man auch ein ? am Anfang des Strings in Perl ersetzen kann?

Hintergrund: Ein Benutzer von collectNWData.sh hat mich darauf hingewiesen, dass die KeyMaskierung dann diesen Fehler ausgibt, wenn der zu maskierende Key mit einem ? anfängt. Das heisst auch das im Ausgabefile collectNWData.txt der Key im Klartext steht :eek:ps:
 

RME

Advanced Hacker
Hallo framp,

Ich kenne Perl nicht, aber normalerweise kann man in solchen Fällen eine oktal oder hex Darstellung anwenden.

Ich würde also folgendes versuchen ('?' = dezimal 63):

"?eins" >>> "\077eins"

"?eins" >>> "\x3feins"

Oder vielleicht funktioniert \e (Escape the next character):

"?eins" >>> "\e?eins"

Gruss,
Roland
 
OP
framp

framp

Moderator
Teammitglied
Ich denke das hat was mit Lookaround Assertions zu tun. Denn
Code:
perl -e '$_="e?ins";s/e?ins/zwei/;print "$_\n"'
hat keine Probleme (Das ? steht nicht am Anfang es Strings)
 
OP
framp

framp

Moderator
Teammitglied
abgdf schrieb:
Meinst Du
Code:
perl -e '$_="?eins";s/\?eins/?zwei/;print "$_\n"'
?
Ich muss wohl doch den genauen Code posten. Ich dachte es ginge mit meinem kleinen Beispiel ...
Code:
function stripWLANKeys() {

$PERL -e '

$mask="@@@@@@";
%keywords = ( "WIRELESS_KEY" => 1,              # SUSE -> /etc/sysconfig/network/ifcfg-*
             "WIRELESS_DEFAULT_KEY" => 1,
             "WIRELESS_KEY_0" =>1,
             "WIRELESS_KEY_1" =>1,
             "WIRELESS_KEY_2" =>1,
             "WIRELESS_KEY_3" =>1,
             "WIRELESS_KEY_LENGTH" =>1,
             "WIRELESS_WPA_IDENTITY" => 1,
             "WIRELESS_WPA_PASSWORD" => 1,
             "WIRELESS_WPA_PSK" => 1,
             "KEY" => 1,                        # RedHat -> /usr/share/doc/initscripts*/sysconfig.txt
             "wpa-psk" => 1,                    # Debian -> /etc/network/interfaces
             "wireless-key" => 1,
                                                # Arch ->
             "WLAN_KEY" => 1,                   # Slackware -> /etc/rc.d/rc.inet1.conf
             "WPAPSK" => 1,
        );


while (<>) {
        my ($key,$value) = /(\w+).*=.*['\''"](\S*)['\''"]/;
        if ($value) {
                if ( exists($keywords{$key})) {
                        s/$value/$mask/;
                }
        }
        print;
}' $1
Das Problem ist, dass der zu maskierende Text vorher in einer regex extrahiert wird und dann per s ersetzt wird. Deine Idee ist schon mal ein Ansatz - aber dann müßte ich vor dem Ersetzen noch alle ? escapen. Das kann ich machen. Ich dachte es gäbe da vielleicht irgendeine Option für s womit man die Interpretation von ? ausschalten kann. Das braucht man ja wirklich nur in Ausnahmefällen...
 
Beim substitute kannst Du viele Zeichen als Feldtrenner verwenden, ich meine unter anderem auch das Fragezeichen. Deshalb läufst Du in diese Probleme, schau mal bei perldoc nach dem s/// sowie regular expressions. Das Stichwort lautet "delimiter". http://perldoc.perl.org/perlre.html dürfte dir einiges erklären, auch wie man solche Konstrukte wie deines baut.
 

abgdf

Guru
Wenn man längere Ausdrücke wörtlich haben will, kann man sie auch zwischen "\Q" und "\E" setzen. Also:
Code:
perl -e '$_="?eins";s/\Q?eins\E/?zwei/;print "$_\n"'
Gruß
 
OP
framp

framp

Moderator
Teammitglied
abgdf schrieb:
Wenn man längere Ausdrücke wörtlich haben will, kann man sie auch zwischen "\Q" und "\E" setzen. Also:
Code:
perl -e '$_="?eins";s/\Q?eins\E/?zwei/;print "$_\n"'
Gruß
:thumbs: Das war es was ich suchte. Von diesen Dingern habe ich noch nie was gehört. Aber wie heisst es auf einer Seite im Netz dazu:
Obscure Perl special characters
 
Oben