define('DEDEADMIN', preg_replace('/[\\/]{1,}/', '/', dirname(__FILE__)));
| 位置 | 字面字元 | 正則意義 | 說明 |
|---|---|---|---|
| 1 | `\` | 反斜線字元本身 | 在字元類別 `[]` 內,`\` 通常不具特殊意義(少數引擎除外),直接匹配反斜線 |
| 2 | `/` | 正斜線字元本身 | 前面的 `\` 將 `/` 轉義為字面字元(雖然 `/` 在 `[]` 內本無特殊意義,但轉義無害) |
結論:`[\\/]` 匹配 **單一字元**:反斜線 `\` **或** 正斜線 `/`。`{1,}` 表示一或多個連續此類字元。整體效果:將路徑中的連續 `/` 或 `\` 統一替換為單一 `/`。
| 寫法 | 結果 | 原因 |
|---|---|---|
| `[\\/]` | 正確 | 匹配 `\` 或 `/` |
| `[/\\]` | 錯誤 | `\\` 在字串中先被解析為單一 `\`,正則見 `[\/]` → `\/` 視為轉義 `/`,`]` 被視為字面字元,導致類別未閉合 → Compile failed: missing terminating ] |
| `[\\\\/]` | 匹配 `\`、`\`、`/` | 字串 `\\\\` → 正則 `\\` → 匹配單一 `\`,重複兩次等同單次 |
| `[/]` | 僅匹配 `/` | 遺漏反斜線,Windows 路徑無法正規化 |
PHP 字串寫法 → PHP 實際字串 → 正則引擎看到
'[\\/]' → [\/] → 字元類別:\ 或 /
"[\\/]" → [\/] → 同上(雙引號同理)
'[\\\\/]' → [\\/] → 字元類別:\ 或 \ 或 /
'/[\\/]{1,}/' → /[\/]{1,}/ → 正則:一或多個 \ 或 /
$path = str_replace('\\', '/', $path); // 簡單、快速、無正則開銷
// 或
$path = preg_replace('#[/\\\\]+#', '/', $path); // 正則版,# 為分隔符避免轉義 /
理解 PHP 字串 → 正則引擎 的雙層轉義,是寫出正確、可維護正則的關鍵。`[\\/]` 看似神秘,拆解後只是「匹配反斜線或正斜線」。下次遇到類似情境,先在腦中跑一次雙層轉義模擬,即可避開陷阱。