PHP: 文字過長加入 WBR tag function

在開發網頁上的程式會有很多的莫名奇妙, 有 IE cache 的 bug, 有人網址到處亂貼, 有人英數字就喜歡長長的打一整排, 然後版面會被撐開變亂.

為了這些問題, 總是得用一堆很 dirty 的方法來解決, ex: 遇到 IE cache 就加個 timestamp 之類的, 讓他不會 cache, 遇到英數字長長一排, 讓版面亂掉的, 就用以下此方法(WBR)來解決.

有人輸入一長串的連續數字, 造成整個頁面過長, 造成版面被撐開.
解決方法: 在那一串的數字中間, 每10個字加 <wbr>(或加個空白也行, 但空白加進去會有點怪), 就能在該斷的時後斷行, 不該斷的時後仍維持一整行.

說明:

WBR 是標準的 Html tag, 作用:you can break HERE if you want, 就是說瀏覽器會判斷是否此處已經在最邊框, 若已經在最邊框, 有 <wbr>的 tag 的話, 就會斷行, 否則就不會(這也是為何不用 <br> 而要使用 <wbr> 的原因).

此種狀況會發生的情況只有以下幾種:

  1. 整串數字(沒有任何空格)
  2. 整串英文(沒有任何空格)
  3. 整串 英文、數字、點 混合(ex: url)

此問題是 broswer 判斷的問題, 在你沒有任何空白分隔的狀況下, broswer 也不敢給你亂斷行, 若你那是一個單字, ex: i18n, 被斷行了, 這在讀的時後就蠻奇怪了. 而此問題對中文和正常的英文文章不會有此問題, 中文瀏覽器可以自行判斷, 英文可以依照空白分格來辨認多長是一個單字.

在此寫一個 function, 在輸出的時後透過此 function 來做輸出動作, 就可以解決此問題.

function insWBR($str, $number = 30)
{
$pattern = "/([\w|\d|\.]\{$number})/";
$replacement = "\\1<wbr>";
return preg_replace($pattern, $replacement, $str);
}

使用方法:

echo insWBR($output, 20); // 每連續20個英數字加一個 wbr tag

PS: 若不想斷行, 可以考慮另一個相反的 tag: <NOBR>, 來包住輸出的字, 就不會被瀏覽器斷行.

Firefox 遇到全形數字也不會自動斷行, 如果要特別處理的話, 可再把下面的判斷($pattern)加進去.

$string = '12345678901234567890123456789012345678901234567890123456789012345678901234567890';
$pattern = '/(((1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(0)){5})/';
$replacement = '$1<wbr>';
echo preg_replace($pattern,$replacement,$string);

感謝 David Chiou 提供改良更完整的 function:

function insWBR($str, $number = 70)
{
    // 因為 2008/1 為止,firefox 的自動斷行在一大串連續英文時無法作用,因此以此函式自動斷行
    $pattern = "/([\w|\d|\.|\`|\~|!|\@|\#|\$|\%|\^|\&|\*|\)|_|\+|\-|=|\[|\]|\\|\{|\} |\||\;|\'|:|\"|\/|\|\?|\/|\,|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(0)]{".$number."})/";
    $replacement = "$1<wbr>";
    return preg_replace($pattern,$replacement,$str);
}

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈PHP: 文字過長加入 WBR tag function〉中有 8 則留言

  1. 不知是否是因為主機設定的關係,我用這串程式無法跑。其中 $pattern 行必須改為
    $pattern = "/([\w|\d|\.]{".$number."})/";
    即可。
    提供作參考。
    另外,在 preg 中印象上沒辦法用中文全形(例如全形數字)去 match,而在我的電腦上沒法成功。或許在 utf-8 編碼下可以?

  2. 剛剛作了進一步測式。Tsung 提供的中文全形的方法是沒問題的,不管是不是 utf-8 編碼。所以整合後整體程式如下的話,在我的電腦的設定下即可跑,提供作參考:
    function insWBR($str, $number = 10)
    {
    $pattern = "/([\w|\d|\.|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(0)]{".$number."})/";
    $replacement = "$1";
    return preg_replace($pattern,$replacement,$str);
    }

  3. 繼續測其餘字元,發現只要是標點等特殊範號,firefox 都無法自動斷行。因此將此函式擴充如下,提供給同好參考:
    function insWBR($str, $number = 70)
    {
    // 因為 2008/1 為止,firefox 的自動斷行在一大串連續英文時無法作用,因此以此函式
    自動斷行
    $pattern = "/([\w|\d|\.|\`|\~|!|\@|\#|\$|\%|\^|\&|\*|\)|_|\+|\-|=|\[|\]|\\|\{|\}|\||\;|\'|:|\"|\/|\|\?|\/|\,|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(0)
    ]{".$number."})/";
    $replacement = "$1";
    return preg_replace($pattern,$replacement,$str);
    }

  4. (上文部份特殊字元無法顯示,還煩請站長幫忙刪除 :))
    感謝Tsung的不棄。
    另外,由於簡繁體甚至 UTF-8 同在文中時,有的中文可能是以 & # 36798 ; (

  5. 嗯嗯, 遇到 & 或 % 這些, 事實上是蠻難處理的, 但是我覺得這都是屬於蠻例外的狀況, 我通常就直接不管他了. XD
    您的解法很棒哩~ 專門為 Firefox 處理這個我倒是沒想過.. Orz..

    1. 這種方式是要解決連續英文字, 中文不會有此問題, 所以不需要用.
      連續英文字(aaaaaaaaa) <-- 這種連在一起, 不知道要哪邊斷掉的.

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料