# 正規表達式

### 說明

在 YOCTOL.AI 中 [觸發條件](https://docs.yoctol.ai/term/trigger) 的 **正規表達式** (Regular Expression)，根據其名可解釋為 描述某種規則的表達式 ，是用來檢索、搜尋或替換符合某個模式或特定排列組合的文字。又名為正規表示式、正則表達式、正規表示法、正規運算式、規則運算式、常規表示法，英文名亦可簡稱 Regexp、Regex 或 RE。

### 範例

我們知道語言的表現方式有百百種，同一句話或是一種表達可以有很多表現方式。又或是不同的表達中有很相似的結構類型。這些可以透過觀察，歸納出某個特定的規則或規律來說明、囊括某一種結構或形式相似的表達。

例如：`大杯紅茶、中杯紅茶、小杯奶茶、中杯綠茶`等，我們可以知道是兩個基本特徵變項的組合： `飲料的尺寸`及`茶飲品項`。

這時我們就可以把`大杯、中杯、小杯`歸納成一類，`紅茶、奶茶、綠茶`歸納成一類。進而推演出一個規則，囊括有各種尺寸的飲料品項的表達。

| 尺寸                    | 品項                    |
| --------------------- | --------------------- |
| <p>大杯<br>中杯<br>小杯</p> | <p>紅茶<br>奶茶<br>綠茶</p> |

而在語言上的寫法就可以透過正規表達式來實現寫出這樣的規則：

> (大|中|小)杯 (紅|奶|綠)茶

### 一般常用場景

正規表達式常被用在蒐集電子郵件、手機號碼、身份證字號或是生日等結構類似的文字表達方面。

> 手機號碼： ^09\d{8}$&#x20;
>
> 身分證字號：^\[A-Z]\d{9}$&#x20;
>
> 電子信箱（以 gmail 為例）：^.\*@gmail.com$&#x20;
>
> 生日：^\d{4}-\d{2}-\d{2}$

### 使用正規表達式的時機

我們在建置聊天機器人時，有時會希望使用者輸入的某些話，可以精確進入某個意圖，進而編寫腳本回應。而這些用語可能展現了特定的文字組合規則，若逐一窮盡舉出，不但耗費時間且有遺漏的可能。

這時，使用正規表達式就是最好的幫手。而常用在建置機器人的情境當中，歸納使用者的話語時，可能想要包括、排除、或是範圍內限定某些表達，例如：要包括特定用詞、排除某種語言、限定第幾個字元為某個字等等。我們在稍後會以 實際範例 來做說明。

### 符碼意義

基本規則：符號是用來限定前面字元允許出現的個數。這邊簡單介紹幾個常用到的表達式符號，更多詳細可以查詢各網站符碼對照表。

| 符號 | 意義       | 舉例  | 表達                    |
| -- | -------- | --- | --------------------- |
| .  | 任一字元     | .   | `你`、`妳`、`我`、`他`       |
| \* | 0 個或以上字元 | 你\* | Ø、`你`、`你你`、`你你你`      |
| +  | 1 個或以上字元 | 你+  | `你`、`你你`、`你你你`、`你你你你` |
| ?  | 0 個或 1 個 | 你?  | Ø、`你`                 |

**^**   開頭限定     e.g.,  ^你好          >>> (符合) `你好`   >>> (不符合) ~~`哈囉你好`~~

**$**  結尾限定   e.g.,   .+吃$            >>> (符合) `我要吃`  >>> (不符合) ~~`我吃東西`~~&#x20;

**|**  或    e.g.,    妳|你                        >>>   `妳`、`你`&#x20;

**( )** 定義操作符的範圍和優先度   e.g.,  (你好|你很好)       >>> `你好`、`你很好`

\[ **]**  字元集合，`[]`其中任一個字元   e.g.,  \[你我他]           >>> `你`、`我`、`他`&#x20;

**{ }** 符號數量範圍，`{}`的數字表示限制的數量  e.g.,    .{2}     >>> `妳好`、`哈囉`、`吃飯`、`走路`&#x20;

&#x20;**\d**  任一數字   e.g.,   \d{3}        >>>  `123`、`333`、`459`

### 情境示例

以服飾電商為情境，我們想訓練一個意圖，知識範圍包含服飾中不同顏色的庫存狀態。

> 對於 `顏色` 和`服飾種類` 的組合有很多種表達：

* 紅色的牛仔褲、藍色的上衣、黃色短褲、綠色薄外套、黃色薄外套、綠色的短褲

不同`顏色`與`服飾種類`的排列組合會有眾多可能，此時就可以利用正規表達式，將所有可能性列出。

| 顏色          | 服飾種類          |
| ----------- | ------------- |
| 紅色、藍色、黃色、綠色 | 牛仔褲、上衣、短褲、薄外套 |

正規表達式可以寫為：

> (紅|藍|黃|綠)色(牛仔褲|短褲|上衣|薄外套)

然而使用者也很可能在字串中間，加入其他的詞來表達，例如 `的`：

* 紅色的上衣、綠色的短褲、紅色的牛仔褲、藍色的上衣、黃色短褲、綠色薄外套、綠色的短褲、深綠色短褲、亮藍色的上衣

在此情況下，正規表達式可寫為：

> (紅|藍|黃|綠)色.?(牛仔褲|短褲|上衣|薄外套)

再更進階一點，我們想要對顏色進行更清楚的描述，例如`淺紅色`、`亮黃`、`深綠`都想要搜尋到，則正規表達式可寫為：

> (淺|亮|深)(紅|藍|黃|綠)色.?(牛仔褲|短褲|上衣|薄外套)

若想抓出搜尋款式樣式的句型，例如：「我要找 OOO 的款式、我想要找 OOO 的樣式的褲子、我想要找 OOO 的樣式的褲子」，正規表達式可寫為：

> ^我(要|想要)找.\*的(款式|樣式)$

### 學習資源

在編寫正規表達式時，除了要熟悉各符號的意義，也需要謹慎確認該表達式是否能正確呈現您想要表達的意思。我們提供幾個網站，供您練習時參考。

* 檢測表達式：[Regex101](https://regex101.com/)
* 檢測表達式：[Regexr](https://regexr.com/)
