PHP

Regular Expressions 正規表達式

利用正規表達式來切割資料

Posted by Young on 2022-10-25
Estimated Reading Time 4 Minutes
Words 1.2k In Total
Viewed Times

概述

最近工作剛好用到正規表達式切割資料,所以就來簡單的講解一下正規表達式的基本用法。

基本語法

這邊介紹一個不錯的網站 Regex Cheat Sheet,可以幫助大家快速瀏覽正規表達式的語法。這下方是我自己較常用到的正規表達式基本語法表格,主要也是給自己日後方便查閱用,日後會繼續更新。

Characters Legend Usage Sample Match
/u 模式修飾符,表示啟用 Unicode 模式 \.\*\+\? \$\^\/\\ .*+? $^/\
\ 避開特殊字元 \.\*\+\? \$\^\/\\ .*+? $^/\
^ 字串開始位置或行開始位置 ^abc.* abc (line start)
+ 比對前一個字元 1 次或以上 /aaabbcc+/ aaa
[xyz] 比對中括弧中任一字元 T[ao]p Tap or Top
\p{L} 匹配任何一種字母 hello “h”, “e”, “l”, “l”, “o”
\p{N} 匹配任何一種數字 123 “1”, “2”, “3”
\p{P} 匹配任何一種標點符號 Hello, World! “,” , “!”

常用正規表達式

台灣手機號碼:/^09\d{8}$/ -> 09xxxxxxxx

  • ^:這個符號表示匹配字符串的開始。這意味著我們希望從字符串的開始進行匹配。
  • 09:這是一個普通字符。這意味著正則表達式要匹配以 “09” 開始的字符串。
  • \d:這個符號表示一個數字字符,等同於 [0-9]。這意味著正則表達式接下來要匹配一個數字。
  • {8}:這個修飾符表示前面的字符(在這個例子中是 \d)應該恰好重複 8 次。這意味著正則表達式接下來要匹配 8 個數字。
  • $:這個符號表示匹配字符串的結尾。這意味著我們希望匹配到字符串的結尾,確保整個字符串與正則表達式匹配。

PHP Regular Expression

這邊由於此欄位在 SQL 的資料型態為varchar(100),大多數的資料都是中英文且特殊符號混雜的情況下,來看看如何使用正規表達式來過濾特殊符號,並且將中英文分離出來。

這次的需求為將產品名稱中的中英文分離出來,只顯示中文部分,並且將英文的部分用隱藏除非游標經過。

這邊使用 preg_match_all() 函數來匹配符合正規表達式的所有內容,並且將匹配到的內容放到一個陣列中。
preg_match_all()是 PHP 中一個用來進行正規表達式匹配的函數。它有三個參數:

  • pattern: 要匹配的正規表達式。
  • subject: 要進行匹配的字符串。
  • matches: 用來存放匹配結果的數組。
1
2
// 定義中英文字符的正規表達式
$pattern = '/([\x{4e00}-\x{9fa5}]+)|([a-zA-Z]+)/u';

正規表達式說明

  • /:表示正規表達式的開始和結束標誌。
  • ([\x{4e00}-\x{9fa5}]+):這是一個捕獲組,用於匹配一個或多個中文字符。\x{4e00} 到 \x{9fa5} 是 Unicode 字符集中漢字的範圍。
  • |:表示或者的意思,用於匹配中文字符或英文字符。
  • ([a-zA-Z]+):這是另一個捕獲組,用於匹配一個或多個英文字符。a-zA-Z 表示所有的大小寫字母。
  • u:是一個修飾符, u表示使用 UTF-8 編碼,這樣可以匹配更多的語言字符集。

舉個例子,如果我們使用這個正規表達式來匹配此產品"2023紓壓複方精油(10ml) relaxing essential complex"字符串,那麼它會返回以下匹配結果。

  • “紓壓複方精油”
  • “ml”
  • “relaxing”
  • “essential”
  • “complex”

若還是不太清楚,可以實際將返回結果印出來,執行以下程式碼,可得到以下結果:

1
2
3
4
5
6
7
8
9
10
11
12
13
$string = "2023紓壓複方精油(10ml) relaxing essential complex";
$pattern = '/([\x{4e00}-\x{9fa5}]+)|([a-zA-Z]+)/u';
preg_match_all($pattern, $string, $matches);
print_r($matches[0]);
// OUTPUT:
Array
(
[0] => 紓壓複方精油
[1] => ml
[2] => relaxing
[3] => essential
[4] => complex
)

可以看到,由於 $matches 是一個陣列,因此匹配結果會儲存在 $matches[0]中,而不是直接儲存在 $matches 中。如果您想要獲取特定捕獲組中的匹配結果,可以使用 $matches[1]$matches[2],它們分別對應到 $pattern 中的第一個和第二個捕獲組。

1
2
3
// 取出匹配的中英文字符
$chinese = implode('', $matches[1]);
$english = implode('', $matches[2]);

結果

最後將分離的中英文字符輸出,如下圖所示:

1
2
// 將分離出來的中英文字符進行輸出
echo "<td><a title='全名為:中文 " . $chinese . " + 英文資訊 " . $english . "'>" . $chinese . "</a></td>";

原本凌亂的表格瞬間就變得較簡潔了且能切割出中英文的資料。
regex_result

正規表達式練習


若您覺得這篇文章對您有幫助,歡迎分享出去讓更多人看到⊂◉‿◉つ~


留言版