如何用 AI 編寫正則表達式並測試:引擎、轉義與 ReDoS 檢查

如何用 AI 編寫正則表達式並測試:引擎、轉義與 ReDoS 檢查

Olivia Park
2026年9月4日· 8 分鐘讀完

要用 AI 編寫正則表達式,先指定引擎與契約,再執行真實測試。遵循如何使用 AI限定範圍;是否有效由目標引擎決定。

關鍵要點

  • 寫清執行環境、引擎、版本、API、標誌及完整匹配或搜尋語義。
  • 先把要求轉成允許清單式契約,再寫語法。
  • 測試接受、拒絕、邊界、Unicode、換行與對抗輸入。
  • 分開處理正則、程式語言字串和命令列外殼轉義。
  • 不只檢查 true/false,還要驗證擷取群組與取代結果。
  • 用受限輸入測試效能,檢查災難性回溯。
  • 表達式難以解釋時改用解析器或普通字串操作。

用 AI 編寫正則表達式前先定義匹配契約

正則無法修復含糊要求。先說明允許與禁止內容、是否匹配完整值,以及後續程式碼會怎樣使用擷取結果。

以一個合成工單編號為例,契約可以是:

欄位決定
合法形狀兩個 ASCII 大寫字母、連字符、四位數字
是否完整匹配是,不允許前後文字
長度恰好 7 個字符
合法例子AB-0042、ZX-9000
非法例子ab-0042、AB 0042、AB-42、XAB-0042Y
擷取前綴和數字部分
輸入來源不可信表格欄位
匹配前長度上限64 個字符

OWASP 建議在輸入驗證中定義允許字符集合及最小、最大長度。[4]範疇允許時優先使用狹窄的允許清單。不要要求「適用於任何識別碼的完美正則」,而要寫明真實語法和政策負責人。

驗證與擷取也要分開。能在段落中找到工單編號的表達式,不應自動用來驗證整個表格值;客戶端便利驗證也不能取代伺服器端執行。

表達式實際由哪個引擎、在哪個呼叫點執行?

JavaScript、Python、Java、.NET、Rust crate、資料庫函式、命令列工具和編輯器的正則並不完全相同。即使語法相同,API 與預設也可能不同。

記錄:

欄位例子
語言/執行環境Python 3.14
引擎/程式庫標準 re 模組
APIre.fullmatch
表達式表示原始字串字面值
標誌無
Unicode 政策契約只允許 ASCII 字母
擷取命名群組 prefix 與 number
取代行為不使用

MDN 說明 JavaScript 標誌會改變全域搜尋、忽略大小寫、多行錨點、點號匹配換行及 Unicode 等行為。[1]Python re 則有自己的語法、標誌、匹配函式與取代反向引用。[2]網上測試器通過不是充分證據,除非它與目標引擎和設定完全一致。

完整匹配、前綴匹配和搜尋是三個不同契約。JavaScript 常用 ^、$ 表達整值驗證,而 Python 可以用 fullmatch 在 API 層表達。仍須測試換行與多行模式行為,不能假定所有錨點語義相同。

在表達式之前建立正則表達式測試案例

測試案例應讓不懂正則語法的負責人也能審批。先用要求給出的例子,再補邊界與近似失敗。

案例輸入預期理由
P-01AB-0042匹配;AB、0042常規合法值
P-02ZX-9000匹配;ZX、9000不同合法值
N-01ab-0042不匹配禁止小寫
N-02AB 0042不匹配分隔符錯誤
N-03AB-42不匹配數字不足
N-04XAB-0042Y不匹配前後多出文字
B-01空字串不匹配最小邊界
B-0264 字符失敗值預算內失敗最大輸入邊界
A-01長重複前綴加 !預算內失敗回溯挑戰

不要讓 AI 同時決定規則與全部預期結果。預言必須來自產品要求、協議、標準或政策。生成測試的方法能擴展矩陣,但標籤由負責人批准。

繼續加入空值、長度邊界上下各一、重複分隔符、嵌入換行、易混 Unicode、首尾空白、呼叫點的 null 處理和超長拒絕值。若擷取內容會進入後續操作,就精確寫出每個擷取值。

要求 AI 同時提供表達式與解釋

提供契約和合成測試表,不提供私人生產樣本。

目標:Python 3.14 標準 re,使用 re.fullmatch 與 raw string。
契約:恰好兩個 ASCII 大寫字母、一個字面連字符、四位數字。
返回一個包含 `prefix` 與 `number` 命名群組的表達式。
逐個符號解釋並列出假設,不得擴大允許字符。
不得創造額外要求;為每個給定案例提供可執行測試。
引擎或轉義不確定項標為 [VERIFY]。

候選可以是:

pattern = r"(?P<prefix>[A-Z]{2})-(?P<number>[0-9]{4})"

由於呼叫點使用 re.fullmatch,此合成例子無需顯式錨點。這是特定引擎和 API 的結論,不是普遍風格要求。要求解釋每個群組、量詞、字符類、分支、前後向斷言與標誌;刪除沒有契約用途的語法。

哪三層轉義必須分開處理?

很多錯誤源於正確的正則被錯誤字串包裹。分別記錄:

  1. 正則語法: 數字類、字面點、群組或反向引用;
  2. 語言字串: 原始碼怎樣表示反斜線與引號;
  3. 傳輸或命令列層: JSON、YAML、命令列或範本怎樣再次編碼。

Python 原始字串通常較易讀,但仍遵守 Python 的原始字串規則。JavaScript 正則字面值和 new RegExp("...") 的字串轉義要求不同。取代字串可能又用另一套語法;Python 文件記錄了 \g<name> 與 \g<number> 等命名和編號引用。[2]

保存原始碼字面值、可查看的執行時表達式值,以及實際執行呼叫。需要時測試字面反斜線、引號、換行和取代擷取。不要靠試錯「修好」轉義而不說明改變哪一層。

如何在目標執行環境測試 AI 生成的正則?

把整套語料放入真實項目測試框架。一個合成 Python 例子如下:

import re

PATTERN = re.compile(r"(?P<prefix>[A-Z]{2})-(?P<number>[0-9]{4})")

def parse_ticket(value: str):
    if len(value) > 64:
        return None
    return PATTERN.fullmatch(value)

assert parse_ticket("AB-0042").groupdict() == {
    "prefix": "AB",
    "number": "0042",
}
assert parse_ticket("ab-0042") is None
assert parse_ticket("XAB-0042Y") is None

長度檢查在匹配前限制工作量,64 只來自合成契約。真實應用還應先檢查類型和 null。即使瀏覽器已驗證,也要執行伺服器端測試。

若正則執行取代,要斷言完整輸出及未匹配部分;若使用全域模式或有狀態 API,要檢查重複呼叫和空匹配;若處理多行,涵蓋兩種常見換行及所選多行模式語義。

檢查 Unicode、標誌、擷取和取代

字符類暗含政策決定。目標引擎的 \d 是 ASCII 數字還是較廣的 Unicode 類別?忽略大小寫會否折疊 A-Z 以外字符?點號會否匹配換行?全域標誌會否在呼叫之間保留狀態?

建立一張覆核表:

維度問題證據
Unicode哪些文字與規範化形式合法?獲批語料
空白空格、製表符、換行是否不同?邊界測試
標誌每個標誌為何存在?執行環境設定
擷取名稱和可選值是否穩定?精確斷言
取代缺失群組怎樣處理?輸出測試夾具
迭代空匹配會否卡住循環?循環測試

不要用僅限 ASCII 的表達式驗證國際姓名,也不要讓協議識別碼意外接受所有 Unicode 數字。政策由產品或協議負責人決定,模型只實作記錄下來的規則。

怎樣測試正則 ReDoS 風險與效能?

部分回溯引擎在特製輸入上會急劇變慢。OWASP 指出,重複群組內再出現重複或重疊分支是典型風險,並列出 (a+)+$ 等例子。[3]因此語料必須包含長失敗輸入。

檢查巢狀歧義量詞、重疊分支、作用於不受控文字的反向引用,以及由用戶輸入構成的表達式。然後:

  1. 在匹配前限制輸入長度;
  2. 適當使用更安全的等價寫法或非回溯引擎;
  3. 在受控程序基準測試普通與對抗失敗;
  4. 執行環境支援安全機制時,在正則外設定逾時或資源邊界;
  5. 記錄引擎、硬件類別、輸入生成方式、次數與門檻。

不要發布通用「10 毫秒內安全」結論。預算屬於具體應用與環境,模型聲稱線性也不是量度或證明。

不要把原始用戶輸入拼入正則。字面搜尋應使用引擎的轉義函式,並繼續限制輸入。若確實允許用戶提供表達式,應視為獨立高風險功能,採用引擎隔離、資源限制與安全覆核。

何時不應使用正則

語法巢狀、依賴上下文或由標準長期維護時,改用普通字串操作、解析器或範疇程式庫。HTML、程式語言、複雜地址和持續變化的業務規則通常不應由一個難以閱讀的表達式獨自承擔。

出現以下情況就停止:

  • 覆核人無法逐個符號解釋;
  • 變體需要重疊巢狀分支;
  • 引擎缺少所需 Unicode 或逾時行為;
  • 擷取群組形成不穩定隱藏 API;
  • 語法之後仍需規範化或語義驗證;
  • 已有維護良好的標準解析器;
  • 測試語料無法清楚描述接受與拒絕邊界。

具體失敗可按AI 除錯流程縮小差異;周邊生成程式碼則採用執行前審查清單。

總結檢查表

  • 用 AI 編寫正則表達式所用的語言、引擎、版本、API、標誌與表示方式已記錄。
  • 契約寫明字符集、長度、完整匹配、擷取與用途。
  • 已有正例、反例、邊界、Unicode、換行及對抗案例。
  • 預期結果來自負責人或標準,不由模型獨自決定。
  • 正則、字串、JSON/YAML 與命令列外殼轉義沒有混淆。
  • 候選在目標環境編譯並執行所有案例。
  • 擷取、取代、重複執行和空匹配均被檢查。
  • 輸入長度受限,ReDoS 風險完成覆核。
  • 另一位維護者能解釋表達式。
  • 正則不合適時改用解析器。

常見問題

只給一個例子,能用 AI 編寫正則表達式嗎?

一個例子無法定義全部接受與拒絕輸入。提供書面契約、正反例、邊界和對抗案例,再在目標引擎執行。

為甚麼用 AI 編寫正則表達式後,網上測試通過但程式碼失敗?

測試器可能使用不同引擎、標誌、匹配 API 或轉義層。必須在項目中重現實際執行時表達式與呼叫點。

應使用錨點還是完整匹配 API?

選擇能在目標引擎中準確表達完整值匹配的寫法。錨點行為可能因引擎而異,因此務必測試嵌入換行和多行模式標誌。

用 AI 編寫正則表達式時,正則轉義與字串轉義有甚麼分別?

正則轉義定義表達式語法,字串轉義定義原始碼怎樣保存它;JSON、YAML、範本和命令列外殼還可能增加更多層。

\d 總是等於 [0-9] 嗎?

不是。某些引擎或模式會讓 \d 匹配較廣的 Unicode 數字。應按輸入政策選擇字符類並加入代表性測試。

用 AI 編寫正則表達式時,怎樣測試 ReDoS 風險?

覆核結構、限制輸入、加入長對抗失敗值,並在真實引擎與受控資源下量度。不能只相信模型的複雜度判斷。

可以把用戶輸入放入正則嗎?

不要把它直接拼成表達式。字面搜尋使用轉義函式;只有明確需要用戶自訂表達式時,才設計隔離和資源上限。

甚麼時候應放棄用 AI 編寫正則表達式,改用解析器?

資料具有巢狀、上下文依賴、標準語法,或小型表達式已無法清楚解釋時,應使用解析器。可維護性也是正確性的一部分。

來源

  1. MDN Web Docs, “Regular expressions” — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions
  2. Python documentation, “re — Regular expression operations” — https://docs.python.org/3/library/re.html
  3. OWASP Foundation, “Regular expression Denial of Service — ReDoS” — https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
  4. OWASP Cheat Sheet Series, “Input Validation” — https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html

Sources checked 2026 年 9 月 4 日。

延伸閱讀

開啟 3 天免費試用

註冊即可免費體驗全部高級功能。

*只限新用戶;每位用戶只可獲得一次試用。

如何用 AI 編寫正則表達式並測試:引擎、轉義與 ReDoS 檢查 | AethoVPN