Regular-Expression
什麼表達式會匹配模式 (^0−90−90-9..a-zA-Z一個−和一個−從a-zA-Z+$) 在 grep 命令中?Linux 重擊
我試圖了解正則表達式
(^[0-9]..[a-zA-Z ]+$)
在命令中檢測到的確切表達式grep
(linux終端)我知道如果我要編寫以下命令:
grep ^[0-9]..[a-zA-Z] filename.txt
92afg
我+$
會檢測到任何包含表達式的行grep ^[0-9]..[a-zA-Z]+$ filename.txt
我試圖打開一個新的文本文件,然後只輸入我認為會被檢測到的表達式,但沒有一個匹配,所以我很感激對此的解釋。
+
代表“前一個或多個重複”,$
是“行尾”。注意與*
with 的區別意味著“零次或多次重複”。所以它基本上意味著:任何以數字開頭的行,後跟兩個任意類型的字元,然後是一個或多個(可能是大寫)字母¹,直到行尾。
(¹要小心,某些語言環境可能不僅有您在 AZ 或 az 中所期望的 26 個字母,例如
è
或ŷ
取決於語言)有關正則表達式的良好指南,我強烈建議grymoire 的美麗網站,我也衷心推薦例如
sed
和awk
。為什麼不匹配?
+
是擴展正則表達式的一部分(否則被解釋為文字+
-符號)。因此,要
+
用作“一個或多個重複”,請使用-E
- 標誌grep
並引用正則表達式以避免 shell 特殊字元的任何問題:grep -E '^[0-9]..[a-zA-Z]+$' filename.txt
讓我們分解一下。首先,請注意此 RegExp 使用“擴展正則表達式”語法 (ERE) - 這
+
是一個元字元,在預設使用的“基本正則表達式”語法中不起作用grep
(這意味著它會匹配自身並需要文字+
在那個位置),所以如果你想使用那個 RegExgrep
,你需要傳遞這個-E
選項。
- 是將
^
正則表達式的這個位置與行首聯繫起來的錨點。- 是一個字元列表,將匹配落入和之間的排序範圍的
[0-9]
任何單個(1)字元。究竟包含什麼取決於“整理順序”,其中包括由環境變數確定的。0``9``LC_COLLATE
.
匹配任何單個字元,因此兩個表示..
“任何兩個字元”。[a-zA-Z]
再次是一個字元列表,將匹配介於 和 之間的字元( 1)以及介於a
和之間的字元。同樣,這意味著什麼取決於整理順序!z``A``Z
- 意思是“以前的
+
一個或多個”- 是將
$
正則表達式的這個位置與行尾聯繫起來的錨點。因此,您的 RegEx旨在(1)匹配任何符合以下條件的行
- 以任何數字開頭
- 後跟任意兩個字元
- 並且只包含直到行尾的字母(但至少一個)。
(1)關於它可能實際做什麼,見下文
一些筆記
- 在您的範例中,您使用不帶引號的正則表達式。
grep
這意味著任何字元在傳遞給命令之前都可以由 shell 解釋。如果您的模式包含$
或通配字元(*
和?
字元[...]
列表!),shell 可能會嘗試執行變數擴展(從而替換您的 RegEx 的一部分)或將通配模式擴展為可能的多個文件名,以便最終您會有更多參數在您最初打算的命令行上。對 shell 來說特殊的其他字元(>
、#
等;
)可能會導致更意想不到的行為。你應該使用grep -E '^[0-9]..[a-zA-Z]+$' filename.txt
反而。
-x
請注意,您可以通過使用標誌強制“整行”匹配來擺脫打開和關閉錨點:grep -x -E '[0-9]..[a-zA-Z]+' filename.txt
- 包含範圍(例如
a-z
)的字元列表很危險,因為它們可能無法給出您的想法。天真地人們可能期望它們匹配位於 ASCII 表上開始和結束字元之間的所有字元,但這僅適用於C
語言環境。在其他語言環境中(特別是在通常設置的系統語言環境中,例如en_US.UTF-8
),排序順序類似於aAbB ... zZ
這樣a-z
也將匹配大多數大寫字母。此外,匹配實際上不是在單個字元級別上,而是在“排序元素”級別上,這意味著在某些語言環境中,甚至幾個字母的組合也可能匹配(例如dzs
在匈牙利語中)!看到這個答案(或者,一般來說,@Stéphane Chazelas 關於模式匹配的大多數答案)以獲得更多洞察力。如果您想確保您的範圍有效,請至少為給定命令設置排序順序LC_COLLATE="C" grep -E ' ... ' filename.txt