php
  • regex
  • 2014-03-26 28 views 1 likes 
    1

    我有兩個preg_match語句可以自己查找,但是當我使用它們時,第二個語句會打破第一個語句;排除preg_match中的字符串

    $message = preg_replace("!(http(s)?://(www\.|m\.)?(youtu\.be/|youtube\.com/watch\?v=)([-|~_0-9A-Za-z]+))!", 
    "<p><a href= '/viewpost.php?messageid=$message_id'><img src='http://img.youtube.com/vi/$5/0.jpg' width='536' border='1'></a><p>", $message); 
    
    $message = preg_replace("!(((f|ht)tp(s)?://)[-a-zA-Z?-??-?()[email protected]:%_+.~#?&;//=]+)!i", "<a href='$1' target='_blank' STYLE='TEXT-DECORATION: NONE'><b>$1</b></a>", 
    $message); 
    

    我最近張貼了這個並獲得建立陣列來的模式和條件,然後在一個單一的preg_match聲明一起將他們的建議,但是這似乎並沒有解決問題(儘管代碼看起來更好)。

    我的想法是在第二個語句中設置一個模式,它將排除在第一個語句中找到的模式(在本例中爲「youtube.com/」和「youtu.be/」),但我不能讓它工作;

    $message = preg_replace("!(http(s)?://(www\.|m\.)?(youtu\.be/|youtube\.com/watch\?v=)([-|~_0-9A-Za-z]+))!", 
    "<p><a href= '/viewpost.php?messageid=$message_id'><img src='http://img.youtube.com/vi/$5/0.jpg' width='536' border='1'></a><p>", $message); 
    
    $message = preg_replace("!(((f|ht)tp(s)?://)/^(?\!\youtube\.|youtu\.be/)[-a-zA-Z?-??-?()[email protected]:%_+.~#?&;//=]+)!i", "<a href='$1' target='_blank' STYLE='TEXT-DECORATION: NONE'><b>$1</b></a>", 
    $message); 
    

    我覺得我已經接近找到一種方法,但我沒有抓住一些東西。

    回答

    1

    你快到了。在你的第二個preg_replace中,你有一些錯誤。

    1. HTTP的部分,然後取出/^(即斜線不存在和^比賽只有字符串的開始)
    2. 正則表達式不編譯,因爲正確的語法排除是?!(意思沒有跟隨),並且這不適用於轉義。我選擇了#作爲開始和結束標記。
    3. 由於您已將youtu.be/...更換爲img.youtube.com/...,因此應該排除該網址。

    工作代碼:

    $message = 'http://youtu.be/watch?v=123 http://www.google.com'; 
    $message_id = 6; 
    
    $message = preg_replace("!(http(s)?://(www\.|m\.)?(youtu\.be/|youtube\.com/watch\?v=)([-|~_0-9A-Za-z]+))!", 
    "<p><a href= '/viewpost.php?messageid=$message_id'><img src='http://img.youtube.com/vi/$5/0.jpg' width='536' border='1'></a><p>", $message); 
    
    $message = preg_replace("#(((f|ht)tp(s)?://)(?!img.youtube.com/vi/)[-a-zA-Z?-??-?()[email protected]:%_+.~\#?&;//=]+)#i", "<a href='$1' target='_blank' STYLE='TEXT-DECORATION: NONE'><b>$1</b></a>", 
    $message); 
    
    echo htmlspecialchars($message); 
    

    除此之外,與preg_replace_callback的解決方案可能會更容易閱讀和容易得多(如果網址與.jpg結束例如內嵌圖片)與未來的選件擴展:

    $message = 'http://youtu.be/watch?v=123 http://www.google.com'; 
    $message_id=6; 
    
    $callback = function($matches) use ($message_id) { 
        $youtube = preg_replace("!(http(s)?://(www\.|m\.)?(youtu\.be/|youtube\.com/watch\?v=)([-|~_0-9A-Za-z]+))!", 
    "<p><a href= '/viewpost.php?messageid=$message_id'><img src='http://img.youtube.com/vi/$5/0.jpg' width='536' border='1'></a><p>", $matches[0], -1, $count); 
        if ($count) { 
         return $youtube; 
        } else { 
         return "<a href='".$matches[0]."' target='_blank' STYLE='TEXT-DECORATION: NONE'><b>".$matches[0]."</b></a>"; 
        } 
    }; 
    
    $message = preg_replace_callback("!(((f|ht)tp(s)?://)[-a-zA-Z?-??-?()[email protected]:%_+.~#?&;//=]+)!i", $callback, $message); 
    
    echo htmlspecialchars($message); 
    

    (注意,使用Closure $callback = function() { ... }至少需要PHP 5.3,否則可以使用命名函數)

    +0

    這完全解決了這個問題。謝謝彼得,我很欣賞這個指導。 – Kimomaru

    相關問題