2016-04-03 4 views
0

Я использую переменную для поиска и замены строки с использованием Perl. Я хочу, чтобы заменить строку 23.0 с 23.0.1, поэтому я попытался это:Perl поиск и замена с помощью переменных, строка содержит точку

my $old="23.0"; 
    my $new="23.0.1"; 
    $_ =~ s/$old/$new/g;   

Проблема заключается в том, что он также заменить строку 2310, поэтому я попытался:

my $old="23\.0" 

, а также /ee. Но он не может получить правильный синтаксис для его работы. Может ли кто-нибудь показать мне правильный синтаксис?

ответ

3

Есть две вещи, которые помогут вам здесь:

quotemeta функция - которая будет бежать метасимволы. А также флаги regex \Q и \E, которые останавливают интерполяцию регулярных выражений.

print quotemeta "21.0"; 

Или:

my $old="23.0"; 
my $new="23.0.1"; 
my $str = "2310"; 
$str =~ s/\Q$old\E/$new/g; 
print $str; 
+0

\ Q и \ E не являются функциями регулярного выражения, они работают везде, где вы делаете интерполяцию с двойным цитированием – ysth

0

В дополнение к отличной ответ Sobrique, позвольте мне отметить, что причина, ваша попытка с "23\.0" не работает, что "23\.0" и "23.0" оценки одной и той же строки: в двойном -quoted string literal, escape-последовательность обратного слэша \. просто оценивает ..

Есть несколько вещей, которые вы могли бы сделать, чтобы избежать этого:

  • Если вы действительно хотите, чтобы соответствовать фиксированной строке, и не нуждаются или хотят включить специальные метасимволы регулярных выражений в нем, вы можете сделайте так, как предложите Собрике и используйте quotemeta или \Q, чтобы избежать их.

    В частности, это почти всегда правильное решение, если строка, подлежащая согласованию, поступает от пользовательского ввода. Если вы do хотите разрешить некоторый ограниченный набор нелитеральных метасимволов, вы можете отменить их после, управляя рисунком через quotemeta. Для простого примера, вот быстрый и грязный способ превратить основной glob -like шаблона (с использованием метасимволов ? и * для «любого символа» и «любая строка символов» repectively) в эквивалентное регулярное выражение:

    my $regexp = "^\Q$glob\E\$"; # quote and anchor the pattern 
    $regexp =~ s/\\\?/./g;  # replace "?" (escaped to "\?" by \Q) with "." 
    $regexp =~ s/\\\*/.*/g;  # replace "*" (escaped to "\*" by \Q) with ".*" 
    
  • И наоборот, если вы хотите иметь буквальное регулярное выражение шаблон в коде, не сразу сопоставления его с чем-то, вы можете использовать qr// регулярное выражение, как цитата оператора, как это:

    my $old = qr/\b23\.0(\.0)?\b/; # match 23.0 or 23.0.0 (but not 123.012!) 
    my $new = "23.0.1";    # just a literal string 
    
    s/$old/$new/g;   # replace any string matching $old in $_ with $new 
    

    Обратите внимание, что qr// имеет другой эффект cts, за исключением того, что вы можете использовать синтаксис regexp в строковом литерале: он на самом деле предварительно компилирует шаблон в специальный объект Regexp, так что его не нужно перекомпилировать каждый раз, когда он используется позже. В частности, в качестве побочного эффекта строковое представление литерала регулярного выражения qr// обычно не соответствует оригинальному контенту, хотя оно будет эквивалентно регулярному выражению. Например, say qr/\b23\.0(\.0)?\b/, на моей версии Perl, выдает (?^u:\b23\.0(\.0)?\b).

  • Вы также можете просто использовать обычный двойной кавычки строкового литерала, и удвоить любые обратные слэши в нем, но это (как правило) менее эффективно, чем использование qr//, а также менее читаемыми из-за leaning toothpick syndrome.

    Использование строкового литерала с одной кавычкой будет немного лучше, так как обратные косые черты в одной кавычной строке являются только специальными, за которыми следует другая обратная косая черта или одиночная кавычка. Тем не менее, читаемость может по-прежнему страдать, если вам понадобится сопоставить любые литеральные обратные косые черты в вашем регулярном выражении, не говоря уже о том, что легко создавать тонкие ошибки, если вы забудете удвоить обратную косую черту в тех редких местах, где она по-прежнему необходима.