PHP

How Smart Tools Are Shaping the Future of Creative Work

Eric Chuang
2020-10-08

今天在幫同事處理一個公司網站的規則運算式 (regular expression) 問題:我用 ACF 客製化的區塊沒辦法正確產生項目符號。

正常的情況應該是這樣:

但是我同事在寫文章的時候變成這樣:

後來上 Regex 101 實驗之後,才發現是自己的規則運算式有問題。原本用來比對的規則運算式如下:

if ( preg_match( '/(\w+)<br\s*\/*>/', $content ) ) {
  	// 將換行標籤 <br /> 與 <br> 取代為 </li><li>,作為項目符號。
    $content = '<ul><li>' . preg_replace( '/(\w+)<br\s*\/*>/', '$1</li><li>', $content ) . '</li></ul>';
} else {
  	// 如果是沒有斷行,則當作段落元素來處理。
    $content = '<p>' . $content . '</p>';
}

用規則運算式比對多位元組字元 (multibyte character)

原本的規則運算式中,使用了 \w 用來比對字串,但 \w 能比對的,只有半形英數,無法用來比對像是中文漢字或日文假名的多位元組字元 (multibyte characters)。如果要改為能夠比對多位元組字元的話,那需要用 \p{L} 這個特殊的字元類別來表示。

此外,如果回頭參考同事使用的字串內容,會發現他的字串中還有其他比對模式需要處理,例如「全形字與半形字中間應有一個半形空格」、「標點符號 %」等,因此需要將規則運算式改寫為下列形式:

if ( preg_match( '/([\w\p{L}\s%!]+)<br\s*\/*>/', $content ) ) {
  	// 將換行標籤 <br /> 與 <br> 取代為 </li><li>,作為項目符號。
    $content = '<ul><li>' . preg_replace( '/([\w\p{L}\s%!]+)<br\s*\/*>/', '$1</li><li>', $content ) . '</li></ul>';
} else {
  	// 如果是沒有斷行,則當作段落元素來處理。
    $content = '<p>' . $content . '</p>';
}

規則運算式的字元類別

關於規則運算式的一般做法,Harris 先生與 Google Analytics 的說明文章都有基本的介紹。這邊要再補充說明字元類別:

名稱說明
\s泛空白字元 (除了半形空格外,也包含 tab、換行等)
\d任何 10 進位數字,相當於 [0-9]
\S非泛空白字元
\D非 10 進位數字字元
[字元組合]比對存在於 [] 間的字元組合,如 [A-Za-z0-9] 相當於 \w
[^字元組合]比對非存在於 [] 間的字元組合
\w比對任何單位元文字字元
\W比對任何非文字字元

其他字元類別的介紹,可以參考 Microsoft 的開發文件。

結語

這次的問題主要是一開始設計不良導致,在測試的過程中,我只用了隨機的英文字串 (如截圖的 abc、def 等),並沒有考慮到實際上寫文章的情形。

Sign up for our newsletter

Subscribe to our newsletter to receive the latest updates, expert insights, and practical tips directly in your inbox. Stay informed with content designed to help you grow.

+480.000 happy customers

Gain more with expert solutions

Unlock the full potential of your business with our expert solutions. Our team provides tailored strategies, professional guidance, and actionable insights to help you achieve better results.

  • Eric Chuang
  • •
  • 2025-01-23
如何同時使用 Webinoly 與 Cloudflare 保護網站安全

在社群夥伴勇哥的文章〈Webinoly 最新版快速安裝〉中,提到使用 Webinoly 來建立 WordPre […]

主機