Domanda

Sto facendo fatica a determinare quali caratteri devono sfuggire quando si usa il qr {} costrutto Perl

Sto tentando di creare una regex precompilata su più righe per il testo che contiene una miriade di caratteri normalmente scappati (# *. >: []) e contiene anche un'altra regex precompilata. Inoltre devo abbinare il più rigorosamente possibile a scopo di test.

my $output = q{# using defaults found in .config
*
*
Options:
  1. opt1
> 2. opt2
choice[1-2?]: };

my $sc = qr{(>|\s)}smx;
my $re = qr{# using defaults found in .config
*
*
Options:
$sc 1. opt1
$sc 2. opt2
choice[1-2?]: }mx;

if ( $output =~ $re ) {
  print "OK!\n";
}
else {
  print "D'oh!\n";
}

Errore:

Quantifier follows nothing in regex; marked by <-- HERE in m/# using defaults found in .config
* <-- HERE 
*
Options:
(?msx-i:(>|\s)) 1. opt1
(?msx-i:(>|\s)) 2. opt2
choice[1-2?]: / at ./so.pl line 14.

Il tentativo di sfuggire agli asterischi provoca una corrispondenza non riuscita (uscita D'oh). Il tentativo di sfuggire ad altri fastidiosi caratteri provoca anche una partita fallita. Potrei continuare a provare diverse combinazioni di cosa sfuggire, ma ci sono molte varianti qui e spero che qualcuno possa fornire alcune informazioni.

È stato utile?

Soluzione

Devi scappare dal delimitatore per qr // e devi scappare da tutti i metacaratteri regex che vuoi usare come valori letterali. Se vuoi che siano letterali *, devi scappare dal momento che * è un quantificatore regex.

Il tuo problema qui sono i vari flag regex che hai aggiunto. / M non fa nulla perché non usi le ancore di inizio o fine stringa (^, $). Il / s non fa nulla perché non si utilizza il carattere jolly. metacarattere. Il / x rende insignificante tutto lo spazio bianco nella tua regex e trasforma quella linea con # in un commento regex.

Questo è quello che vuoi, con i flag regex rimossi e le cose appropriate sono sfuggite:

my $sc = qr{(>|\s)};

my $re = qr{# using defaults found in \.config
\*
\*
Options:
$sc 1\. opt1
$sc 2\. opt2
choice\[1-2\?]: };

Anche se Damian Conway dice alle persone nelle Best Practices di Perl di mettere sempre queste opzioni sulla loro regex, ora capisci perché ha torto. Dovresti aggiungerli solo quando vuoi quello che fanno, e dovresti aggiungere cose solo quando sai cosa fanno. :) Ecco cosa potresti fare se vuoi usare / x. Devi sfuggire a qualsiasi spazio bianco letterale, devi indicare in qualche modo le terminazioni di linea e devi sfuggire al carattere letterale #. Ciò che era leggibile prima è ora un casino:

my $sc  = qr{(>|\s)};
my $eol = qr{[\r\n]+};

my $re  = qr{\# \s+ using \s+ defaults \s+ found \s+ in \s+ \.config $eol
\*                    $eol
\*                    $eol
Options:              $eol
$sc \s+ 1\. \s+ opt1   $eol
$sc \s+ 2\. \s+ opt2   $eol
choice\[1-2\?]: \s+
}x;

if ( $output =~ $re ) {
  print "OK!\n";
}
else {
  print "D'oh!\n";
}

Altri suggerimenti

Suona come quello che vuoi veramente è Expect , ma la cosa che sono immediatamente alla ricerca dell'operatore quotemeta che sfugge a tutti i personaggi che hanno significati speciali in un regex.

Per rispondere direttamente alla tua domanda (comunque), oltre al carattere non quotato (in questo caso } ) devi scappare almeno, . [$ () | * + ? {\

Come ha detto Brian, devi scappare dal delimitatore e dai regex metacaratteri. Nota che quando usi qr // x (che sei), devi anche sfuggire ai caratteri degli spazi bianchi e # (che è un marcatore di commento). Probabilmente non vuoi effettivamente usare / x qui. Se vuoi essere al sicuro, puoi sfuggire a qualsiasi carattere non alfanumerico.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top