2017-11-30 72 views
6

W podstawieniu tekstowym perl są bardzo proste i potężne. chcę zrobić skrypt ze zmiennymi substytucji, jak:Jak zastąpić zmiennymi opcjami w skrypcie perla

if ($IgnoreCase) {$opt = "gi"} else {$opt = "g"} 

$string =~ s/$source/$replace/$opt; 

Wyniki w: znaleziono

Scalar gdzie operator expected ...

Czy istnieje możliwość spotkania się wykonać zmienna opcji?

Odpowiedz

13

Ponieważ używasz /g we wszystkich przypadkach można,

my $opt = $IgnoreCase ? "(?i)" : ""; 

$string =~ s/$opt$source/$replace/g; 

Więcej na ten temat w perldoc perlre

jeden lub więcej wbudowanych modyfikatorów wzorca dopasowania, aby włączyć (lub wyłączone, jeśli jest poprzedzone "-") dla pozostałej części wzorca lub pozostałej części otaczającej grupy wzorów (jeśli istnieją).

Jest to szczególnie użyteczne w przypadku dynamicznie generowanych wzorców, takich jak te pobierane z pliku konfiguracyjnego, pobierane z argumentu lub określone gdzieś w tabeli. Rozważmy przypadek, w którym niektóre wzorce chcą uwzględniać wielkość liter, a niektóre nie. Rozróżnianie wielkości liter nie musi uwzględniać wielkości liter (? I) na początku wzorca.

+1

Czy mógłbyś wyjaśnić trochę? – ssr1012

+0

Dziękuję za szybką odpowiedź. Ono doskonale mnie kształtuje. – Horst

+3

Rzeczy takie jak 'i' mogą być dostarczane w czasie wykonywania za pomocą nawiasów, aby je ponownie włączyć i wyłączyć. Nie można tego zrobić za pomocą 'g' chociaż, ponieważ zasadniczo zmienia zachowanie silnika regex. – Sobrique

7

Aby nieco wyjaśnić the excellent answer z Сухой27:

Jak widać, nie można użyć zmiennej w sekcji Opcje operatora s/// (dobrze, jeśli można stosować eval ale to byłoby bardzo zły pomysł).

Jednak to nie jedyny sposób, aby uzyskać opcje dopasowania do wyrażenia regularnego. Można również użyć ciągu regex z (?...) wewnątrz . Na przykład m/(?i)foo/ jest dokładnie taki sam, jak m/foo/i. Zauważ, że /g to nieco inna klasa opcji, więc nie możesz użyć tej opcji w ten sposób.

Ale ponieważ ten ciąg (?...) jest tylko częścią wyrażenia regularnego, można użyć zmiennej do osadzenia jej w swoim regex.

my $opt = $IgnoreCase ? "(?i)" : ""; 

$string =~ s/$opt$source/$replace/g; 

Aby uzyskać więcej informacji, zobacz numer "Extended Patterns" in perldoc perlre.

+0

Czy istnieje sposób na zmienne tej klasy opcji (jak/g)? – Horst

+2

@Horst: Nie, ponieważ opcja '/ g' zmienia sposób, w jaki silnik regex działa w fundamentalny sposób - a po uruchomieniu silnika jest już za późno, aby go zmienić. –

+0

Innym sposobem radzenia sobie z tym problemem byłby trzeci operator lub struktura kontrolna if-else, która nie zapewnia po prostu odpowiednich opcji, ale idzie dalej i dostarcza całego regexu. Wtedy opcja/g może być w jednym, a nie w drugiej. –

Powiązane problemy