sbarazzarsi del vostro parametro $caseSensitive
, come sarà inutile in molti casi. Al contrario, gli utenti di tale funzione possono codificare le informazioni necessarie direttamente nella regex $validationRe
.
Quando si crea un oggetto regex come qr/foo/
, il motivo è in quel punto compilato nelle istruzioni per il motore regex. Se si stringifica un oggetto regex, si otterrà una stringa che, una volta interpolata in un'espressione regolare, avrà esattamente lo stesso comportamento dell'oggetto regex originale. Soprattutto, ciò significa che tutti i flag forniti o omessi dal letterale dell'oggetto regex saranno preservati e non possono essere sovrascritti! Questo è di progettazione, in modo che un oggetto regex continui a comportarsi in modo identico indipendentemente dal contesto in cui viene utilizzato.
Questo è un po 'asciutto, quindi usiamo un esempio. Ecco una funzione match
che tenta di applicare un paio di regex simili a un elenco di stringhe. Quale abbinerà?
use strict;
use warnings;
use feature 'say';
# This sub takes a string to match on, a regex, and a case insensitive marker.
# The regex will be recompiled to anchor at the start and end of the string.
sub match {
my ($str, $re, $i) = @_;
return $str =~ /\A$re\z/i if $i;
return $str =~ /\A$re\z/;
}
my @words = qw/foo FOO foO/;
my $real_regex = qr/foo/;
my $fake_regex = 'foo';
for my $re ($fake_regex, $real_regex) {
for my $i (0, 1) {
for my $word (@words) {
my $match = 0+ match($word, $re, $i);
my $output = qq("$word" =~ /$re/);
$output .= "i" if $i;
say "$output\t-->" . uc($match ? "match" : "fail");
}
}
}
uscita:
"foo" =~ /foo/ -->MATCH
"FOO" =~ /foo/ -->FAIL
"foO" =~ /foo/ -->FAIL
"foo" =~ /foo/i -->MATCH
"FOO" =~ /foo/i -->MATCH
"foO" =~ /foo/i -->MATCH
"foo" =~ /(?^:foo)/ -->MATCH
"FOO" =~ /(?^:foo)/ -->FAIL
"foO" =~ /(?^:foo)/ -->FAIL
"foo" =~ /(?^:foo)/i -->MATCH
"FOO" =~ /(?^:foo)/i -->FAIL
"foO" =~ /(?^:foo)/i -->FAIL
In primo luogo, dobbiamo notare che la rappresentazione di stringa di oggetti regex ha questo strano (?^:...)
modulo. In un gruppo non catturante (?: ...)
, i modificatori per il modello all'interno del gruppo possono essere aggiunti o rimossi tra il punto interrogativo ei due punti, mentre lo ^
indica il set predefinito di contrassegni.
Ora, quando osserviamo la frase regex falsa che in realtà è solo una stringa che viene interpolata, possiamo vedere che l'aggiunta del flag /i
fa la differenza come previsto. Ma quando usiamo un oggetto regex reale, non cambia nulla: l'esterno /i
non può sostituire i flag (?^: ...)
.
Probabilmente è meglio presumere che tutte le espressioni regolari siano già oggetti regex e non dovrebbero essere interferite con. Se carichi i modelli regex da un file, dovresti richiedere che le espressioni regolari utilizzino la sintassi (?: ...)
per applicare la tecnica flages (ad esempio come equivalente a qr/foo/i
). Per esempio. caricamento di un'espressione regolare per riga da un handle di file potrebbe essere simile a:
my @regexes;
while (<$fh>) {
chomp;
push @regexes, qr/$_/; # will die here on regex syntax errors
}
oppure c'è un modo migliore per fare ciò che voglio fare? – livefree75