string
  • perl
  • substitution
  • 2013-03-13 90 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 2013-03-13 04:26:53

    +1

    @MkV你的意思是*癮* *? – gaussblurinc 2013-03-13 07:27:26

    回答

    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> 
    

    爲了逃避從您的字符串這些字符,最好是隻使用Perl的quotemeta功能:

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

    這將逃避你的特殊字符,然後你的正則表達式替換將正常工作。

    編輯

    既然你有因爲非轉義字符正則表達式的問題,因爲它不要求你逃脫任何字符這種解決方案可能是簡單的:

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

    這是基於關本實施例的:

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

    在perldocs文檔發現substr

    +1

    你絕對是在正確的軌道上;主要的麻煩製造者是'?';在這種情況下,斜線實際上不是問題(僅在'?'的前面加一個反斜槓,然後試一下)。 '.'字符會很快樂地匹配'.'(以及其他任何東西)。事實上,一個字符串不太可能因爲點而導致問題。 – 2013-03-13 04:23:09

    +0

    @JonathanLeffler,得到了你。感謝您的澄清! :) – srchulo 2013-03-13 05:06:54

    +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)字符串成爲默認字符串時,它可能會導致不必要的副本。 – 2013-03-13 22:06:06

    2

    該問題可以通過在腳本中添加兩個字符來解決。你需要的是在$string2逃跑元字符:

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

    導致比賽失敗的字符是問號?,在這裏轉義...aspx?...手段「匹配0或者字符‘X’1」。字符.是與除換行符以外的任何內容匹配的通配符,這可能會導致錯誤匹配。斜槓/由於是替代運算符s///的分隔符而爲元字符,因爲它們嵌入字符串中,所以不需要轉義。

    使用\Q ... \E轉義序列,在正則表達式中或使用quotemeta可以很容易地轉義元字符。

    嘗試和手動轉義這些類型的字符串並不是一個好主意,特別是如果文字匹配是所有必需的話。

    +0

    '?'是阻止匹配的唯一字符。這兩個'''也可能變成*麻煩*。 – 2013-03-13 21:28:20

    +0

    @BradGilbert我不確定你的消息是與這個評論。 – TLP 2013-03-13 22:24:45

    +0

    如果你只修改'?'。它仍然可以匹配'http://www_aaa.com/downloads/details.aspx?FamilyID = a1b2c3'(將'_'換成第一個'.')。這會使第一個問題成爲問題。 (評論主要是爲了這個答案的未來觀衆) – 2013-03-14 00:24:37

    相關問題