正則表達式中 “$” 並不是表示 “字符串結束

作者:Seth Larson

譯者:豌豆花下貓@Python貓

英文:Regex character “$” doesn't mean “end-of-string”

轉載請保留作者及譯者信息

這篇文章寫一寫我最近在用 Python 的正則表達式模塊(re)開發 CPython 的 SBOM 工具時發現的一個令人驚訝的行爲。

如果用過正則表達式,你可能知道 ^ 表示 “字符串開始”,並相應地將 $ 視爲 “字符串結束”。因此認爲, cat$ 模式會匹配字符串 "lolcat" ,但不會匹配 "internet cat video"

^ 的行爲讓我認爲 $ 也是類似的,但這並不一定成立,而且這種行爲取決於不同編程語言及其寫法。

特別是對於 Python 來說,如果禁用了多行模式(這是默認設置),那麼,$ 字符不僅可以匹配字符串的末尾,還可以匹配字符串末尾的換行符。

所以,如果你試圖匹配一個末尾沒有換行符的字符串,在 Python 中使用 $ 是做不到的!我本以爲禁用多行模式後,就不會有這種匹配換行符的行爲,但事實恰恰相反。

下一個合乎邏輯的問題是,如何在 Python 中匹配一個末尾不含換行符的字符串?

在對 Python其它正則表達式語法進行多番研究後,我還發現了 \z\Z 可以用於匹配 “字符串結束” 字符。

在 Python 中,可以用 re.MULTILINE 來啓用多行模式,文檔的描述如下:

當指定 re.MULTILINE 時,模式字符 '$' 會匹配字符串末尾以及每一行末尾(包含換行符)。默認情況下,'$' 只匹配字符串末尾以及字符串末尾的換行符之前(如果有的話)。

讓我們看看這些特性在不同平臺上是什麼表現:

模式匹配 "cat\n"? "cat$" 多行模式 "cat$" 無多行模式 "cat\z" "cat\Z"
PHP
ECMAScript ⚠️ ⚠️
Python ⚠️
Golang ⚠️
Java 8
.NET 7.0
Rust ⚠️
  • ✅: 模式與字符串 "cat\n" 匹配
  • ❌: 模式與字符串 "cat\n" 不匹配
  • ⚠️: 模式無效或不支持該用法

綜合上述表格,如果要匹配換行符,那麼在所有語言中使用多行模式的 $ ,都能匹配成功;但如果不想匹配換行符,事情就會變得複雜起來。

如果不想匹配換行符,在除了 Python 和 ECMAScript 外的其它語言中,你可以使用 \z。而在 Python 中,你需要使用 \Z ,在 ECMAScript 中使用非多行模式的 $

今天這些關於正則表達式的知識,你學會了麼?

注意:上述數據表的信息收集自 regex101.com,我沒有用實際的編程環境進行測試。


以上是今天的分享,最後推薦一下我的《Python潮流週刊》專欄。這是一個專爲國內 Python 開發者量身打造的資訊平臺,爲你挑選最值得分享的文章、教程、開源項目、軟件工具、播客和視頻、熱門話題等內容。

https://xiaobot.net/p/python_weekly?refer=2fc438e2-33fe-44bd-aa2f-ae7d8e782dea

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章