string
  • perl
  • substitution
  • 2013-03-13 2 views -1 likes 
    -1

    Ниже мои коды:простая строка подстановки не работает

    my $string1 = '<td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td>'; 
    my $string2 = 'http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3'; 
    
    
    print "Before string substitution:\n$string1\n"; 
    $string1 =~ s/$string2//; 
    print "After string substitution:\n$string1\n"; 
    

    И фактический выход:

    Before string substitution: 
    <td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td> 
    After string substitution: 
    <td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td> 
    

    Что я ожидаю:

    Before string substitution: 
    <td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td> 
    After string substitution: 
    <td><a href="">abcdefg</a><br />(123456)</td> 
    

    может кто-то пожалуйста, скажите мне что не так в моем коде?

    Спасибо.

    +3

    HTML и регулярные выражения, роковые притяжения. – MkV

    +1

    @MkV вы имеете в виду * наркомания *? – gaussblurinc

    ответ

    1

    Поскольку вы помещаете в символах, которые считаются специальные символы PERL регулярное выражение, вы должны избежать их, как это:

    my $string2 = 'http:\/\/www\.aaa\.com\/downloads\/details\.aspx\?FamilyID=a1b2c3'; 
    

    Затем ожидаемый выход будет отображаться при запуске программы:

    <td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td> 
    After string substitution: 
    <td><a href="">abcdefg</a><br />(123456)</td> 
    

    чтобы избежать этих символов из вашей строки, то лучше всего использовать quotemeta функция языка Perl:

    my $string2 = quotemeta('http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3'); 
    

    Это позволит избежать специальных символов для вас, а затем замена вашего регулярного выражения будет работать нормально.

    EDIT

    Поскольку у вас возникли проблемы из-за не-спасся регулярных выражений символов, это решение может быть проще, так как она не требует от вас, чтобы избежать каких-либо символов:

    substr($string1, index($string1,$string2), length($string2)) = ''; 
    

    Это основаны от этого примера:

    my $name = 'fred'; 
    substr($name, 4) = 'dy'; # $name is now 'freddy' 
    

    найдены в perldocs для substr.

    +1

    Ты определенно на правильном пути; основным нарушителем проблемы является '?'; косые черты на самом деле не являются проблемой в этом контексте (поставьте обратную косую черту перед '?' и попробуйте). Символы '.' Будут соответствовать '.' довольно счастливо (как и все остальное). Фактически, маловероятно, что строка вызовет проблемы из-за точек. –

    +0

    @ JonathanLeffler, получил я. Спасибо за разъяснения! :) – srchulo

    +0

    Ваш ['substr'] (http://p3rl.org/substr" perldoc -f substr ") пример должен быть почти' {my $ index = index ($ string1, $ string2), if ($ index> = $ [) {substr ($ string1, $ index, length ($ string2), '')}} '. Теперь у вас есть добавленная пустая строка в конец '$ string1', если она не совпадает. Сейчас это не большая проблема, но в будущем это может привести к ненужной копии, когда по умолчанию становятся строки [COW] (https://en.wikipedia.org/wiki/Copy-on-write). –

    2

    Эта проблема может быть исправлена ​​путем добавления двух символов в ваш скрипт. Что вам нужно, чтобы избежать мета-символов в $string2:

    $string1 =~ s/\Q$string2//; 
    

    Символа, который вызывает матч на провал является вопросительным знаком ?, который незаменяемое здесь ...aspx?... означает «матч 0 или 1 символ„х“». Символы . являются подстановочными знаками, которые соответствуют чему-либо, кроме новой строки, что может привести к ложноположительным совпадениям. Косые черты /, будучи метасимволами из-за того, что они являются разделителем оператора замещения s///, не требуют экранирования, поскольку они встроены в строку.

    Экранирование метасимволов наиболее легко выполняется с помощью escape-последовательности \Q ... \E внутри регулярного выражения или с помощью quotemeta.

    Не рекомендуется пытаться избежать этих типов строк вручную, особенно если требуются только литературные совпадения.

    +0

    '?' - единственный символ, который мешает ему совместить. Два '.' могут также стать * неприятными *. –

    +0

    @BradGilbert Я не уверен, что ваше сообщение с этим комментарием. – TLP

    +0

    Если вы только установили '?'. Он все равно может соответствовать 'http: //www_aaa.com/downloads/details.aspx? FamilyID = a1b2c3' (замените первый' .' для '_'). Что сделало бы первую проблему. (Комментарий был в основном для будущих зрителей этого ответа) –

    Смежные вопросы