快速入門
教學
工具和語言
範例
參考
書籍評論
正規表示式教學
簡介
目錄
特殊字元
不可列印字元
正規表示式引擎內部
字元類別
字元類別減法
字元類別交集
簡寫字元類別
錨點
字詞邊界
交替
可選項目
重複
群組和擷取
反向參照
反向參照,第 2 部分
命名群組
相對反向參照
分支重設群組
自由間距和註解
Unicode
模式修改器
原子群組
獨佔量詞
前瞻和後顧
環顧,第 2 部分
將文字排除在比對之外
條件式
平衡群組
遞迴
子常式
無限遞迴
遞迴和量詞
遞迴和擷取
遞迴和反向參照
遞迴和回溯
POSIX 方括號表示式
零長度比對
持續比對
本網站的其他內容
簡介
正規表示式快速入門
正規表示式教學
替換字串教學
應用程式和語言
正規表示式範例
正規表示式參考
替換字串參考
書籍評論
可列印 PDF
關於本網站
RSS 饋送和部落格
RegexBuddy—Better than a regular expression tutorial!

自由間距正規表示式

大部分現代的正規表示法風味都支援一種稱為自由間距模式的正規表示法語法變體。此模式允許使用更易於閱讀的正規表示法。在本教學課程中討論的風味中,只有 XML SchemaPOSIXGNU 風味不支援此模式。純 JavaScript 也不支援,但 XRegExp 支援。此模式通常透過設定正規表示法外的選項或旗標來啟用。對於支援 模式修改器 的風味,您可以在正規表示法的開頭放置 (?x),以使正規表示法的其餘部分為自由間距。

在自由間距模式中,正規表示法記號之間的空白會被忽略。空白包括空格、標籤和換行符。請注意,只有記號之間的空白會被忽略。在自由間距模式中,a b cabc 相同。但 d\d 不同。前者比對  d,而後者比對數字。 \d 是由反斜線和「d」組成的單一正規表示法記號。使用空白中斷記號會產生跳脫空白(比對空白)和文字「d」。

同樣地,群組修改器無法中斷。 (?>atomic)(?> ato mic )( ?>ato mic) 相同。它們都比對相同的 原子群組。它們與 (? >atomic) 不同。後者是語法錯誤。 ?> 群組修改器是正規表示法語法中的單一元素,且必須保持在一起。這適用於所有此類建構,包括 環顧命名群組 等。

哪些空白和換行符會被忽略取決於正規表示法風味。本 教學課程 中討論的所有風味都忽略 ASCII 空白、標籤、換行符、回車符和換頁符字元。 JGsoft V2Boost 是唯一忽略所有 Unicode 空白和換行符的風味。JGsoft V1 幾乎忽略所有,但錯過下一行控制字元 (U+0085)。Perl 始終將非 ASCII 空白視為文字。Perl 5.22 及更新版本忽略非 ASCII 換行符。Perl 5.16 及更早版本將其視為文字。Perl 5.18 和 5.20 將未跳脫的非 ASCII 換行符視為自由間距模式中的錯誤,以提供開發人員過渡期。

字元類別中的自由間距

字元類別通常視為單一記號。 [abc][ a b c ] 不同。前者比對三個字母中的其中一個,而後者比對這三個字母或一個空白。換句話說:自由間距模式在字元類別內無效。字元類別內的空白和換行會包含在字元類別中。這表示在自由間距模式中,您可以使用 [ ] 比對單一空白。使用您覺得較好讀取的方式。當然,十六進位跳脫字元 \x20 也適用。

不過,Java 在自由間距模式中不會將字元類別視為單一記號。Java 會忽略字元類別內的空白、換行和註解。因此在 Java 的自由間距模式中,[abc][ a b c ] 相同。若要將空白加入字元類別,您必須使用反斜線跳脫它。但即使在自由間距模式中,否定插入符號也必須緊接在開啟方括號之後。 [ ^ a b c ] 比對四個字元 ^abc 中的任何一個,就像 [abc^] 一樣。否定插入符號在正確的位置時,[^ a b c ] 比對任何不是 abc 的字元。

Perl 5.26 提供有限的字元類別內自由間距作為選項。 /x 旗標僅啟用字元類別外的自由間距,如同 Perl 的先前版本。雙重 /xx 旗標另外讓 Perl 5.26 將字元類別內未跳脫的空白和 tab 視為自由空白。換行在字元類別內仍為字面意義。如果您將 PCRE2_EXTENDED_MORE 旗標傳遞給 pcre2_compile(),PCRE2 10.30 支援與 Perl 5.26 相同的 /xx 模式。

Perl 5.26 和 PCRE 10.30 也新增一個新的模式修改子 (?xx),它啟用字元類別內外皆為自由間距。 (?x) 會像以前一樣開啟字元類別外的自由間距,但也會關閉字元類別內的自由間距。 (?-x)(?-xx) 都會完全關閉自由間距。

Java 將 ^ 視為 [ ^ a ] 中的文字。即使忽略空白,它們仍會中斷 Java 中插入符號的特殊含義。Perl 5.26 和 PCRE2 10.30 將 ^ 視為 [ ^ a ] 中的否定插入符號,並處於 /xx 模式。Perl 5.26 和 PCRE2 10.30 完全忽略自由空白。它們仍將插入符號視為字元類別的開頭。

自由間距模式中的註解

自由間距模式的另一個特色是 # 字元會開始註解。註解會一直持續到該行的結尾。從 # 到下一個換行字元的任何內容都會被忽略。大多數的風格都不會辨識任何其他換行字元為註解的結尾,即使它們將其他換行字元辨識為自由空白或允許 錨點與其他換行字元相符。JGsoft V2 是唯一辨識所有 Unicode 換行字元的風格。Boost 會遺漏垂直標籤。

XPathOracle 不支援正規表示式中的註解,即使它們有自由間距模式。它們總是將 # 視為文字字元。

Java 是唯一在自由間距模式中將 # 視為字元類別內註解開頭的風格。註解會持續到該行的結尾,因此您可以使用 ] 來關閉註解。所有其他風格都將 # 視為字元類別內的文字。這包括處於 /xx 模式的 Perl 5.26。

將所有內容放在一起,用於比對有效日期的正規表示式 可以透過寫在多行來釐清

# 比對 yyyy-mm-dd 格式的 20 或 21 世紀日期
((?:19|20)\d\d)            # 年 (群組 1)
[- /.]                     # 分隔符號
(0[1-9]|1[012])            # 月 (群組 2)
[- /.]                     # 分隔符號
(0[1-9]|[12][0-9]|3[01])   # 日 (群組 3)

RegexBuddy makes regular expressions more readable with syntax coloring

無自由間隔的註解

許多風味也允許您在不使用自由間隔模式的情況下,將註解新增到正規表示式中。語法為 (?#comment),其中「comment」可以是您想要的任何內容,只要不包含右括號即可。正規表示式引擎會忽略 (?# 之後到第一個右括號之間的所有內容。

在本教學課程中討論的風味中,所有支援自由間隔模式中註解的風味(JavaTcl 除外),也支援 (?#comment)。不支援自由間隔模式中註解或根本不支援自由間隔模式的風味,也不支援 (?#comment)