Double Commander

2.14. 正規表示式語法

內容

1. 介紹
2. 簡單匹配
3. 跳脫序列
4. 字元類
5. 元字元
5.1. 元字元 - 行分隔符
5.2. 元字元 - 預定義類
5.3. 元字元 - 詞邊界
5.4. 元字元 - 迭代器
5.5. 元字元 - 替代項
5.6. 元字元 - 子表示式
5.7. 元字元 - 反向引用
6. 斷言(前瞻和後瞻斷言)
7. 非捕獲組
8. 原子組
9. Unicode類別
10. 修飾符

Double Commander使用Andrey Sorokin編寫的免費庫TRegExpr

大多數解釋來自該庫的說明文件。

1. 介紹

正規表示式是一種廣泛使用的指定文字搜尋模式的方法。特殊字元(元字元)允許我們指定,例如,我們正在尋找的特定字串出現在行的開頭或結尾,或者包含字元或字元組的n次出現。

Double Commander在以下功能中支援正規表示式:

TRegExp庫支援兩種操作模式:ANSI和Unicode。在文字檔案中搜尋時,Double Commander使用兩者(取決於檔案編碼)。在按名稱搜尋時,使用Unicode。

2. 簡單匹配

任何單個字元都匹配自身,除非它是一個具有下面描述的特殊含義的元字元。

一系列字元匹配目標字串中的該系列字元,因此模式bluh將匹配目標字串中的bluh

我們可以通過在元字元或跳脫序列前面加上反斜線\來使它們被逐字解釋,例如:元字元^匹配字串開頭,但\^匹配字元^\\匹配\等等。

以下是一些示例:

簡單匹配示例
表示式結果
foobar
匹配字串foobar
\^FooBarPtr
匹配^FooBarPtr

3. 跳脫序列

可以使用類似於C和Perl中使用的跳脫序列語法來指定字元:\n匹配換行符,\t匹配製表符等。

更一般地,\xnn,其中nn是一串十六進位數字,匹配ASCII值為nn的字元。

如果您需要寬(Unicode)字元程式碼,可以使用\x{nnnn},其中nnnn – 一個或多個十六進位數字。

跳脫序列
表示式結果
\xnn
ASCII程式碼為nn的字元
\x{nnnn}
ASCII程式碼為nnnn的字元(普通文字為一個位元組,Unicode為兩個位元組)
\t
製表符(HT/TAB),與\x09相同
\n
換行符(NL/LF),與\x0a相同
\r
回車符(CR),與\x0d相同
\f
換頁符(FF),與\x0c相同
\a
警報(鈴聲)(BEL),與\x07相同
\e
跳脫(ESC),與\x1b相同

以下是一些示例:

跳脫序列示例
表示式結果
foo\x20bar
匹配foo bar(注意中間的空格)
\tfoobar
匹配由製表符預定義的foobar

4. 字元類

您可以通過將字元列表括在[]中來指定字元類,這將匹配列表中的任何一個字元。

如果[後的第一個字元是^,則該類匹配列表中包含的任何字元。

在列表中,-字元用於指定範圍,因此a-z表示從az的所有字元,包括在內。

如果您希望-本身成為類的成員,請將其放在列表的開頭或結尾,或用反斜線跳脫。

如果您希望使用],可以將其放在列表的開頭或用反斜線跳脫。

字元類
表示式結果
[-az]
匹配az-
[az-]
匹配az-
[a\-z]
匹配az-
[a-z]
匹配從az的所有26個小寫字母
[\n-\x0D]
匹配任何\x10\x11\x12\x13
[\d-t]
匹配任何數字、-t
[]-a]
匹配從]a的任何字元

以下是一些示例:

字元類示例
表示式結果
foob[aeiou]r
尋找字串foobarfoober等,但不包括foobbrfoobcr等。
foob[^aeiou]r
尋找字串foobbrfoobcr等,但不包括foobarfoober等。

5. 元字元

元字元是正規表示式的精髓,是特殊字元。

有不同的元字元類型,如下所述。

5.1. 元字元 - 行分隔符

一些表示式有助於檢測行分隔。

行分隔符
表示式結果
^
行首
$
行尾
\A
文字開頭
\Z
文字結尾
.
行中任何字元

以下是一些示例:

行分隔符示例
表示式結果
^foobar
僅當字串foobar在行首時匹配
foobar$
僅當字串foobar在行尾時匹配
^foobar$
僅當字串foobar是行中唯一字串時匹配
foob.r
匹配像foobarfoobbrfoob1r等字串

預設情況下,^元字元僅保證在輸入字串/文字的開頭匹配,$元字元僅在末尾匹配。嵌入的行分隔符不會被^$匹配。

但是,您可能希望將字串視為多行緩衝區,這樣^將在字串內的任何行分隔符後匹配,$將在任何行分隔符前匹配。您可以通過打開修飾符m來實現。

\A\Z就像^$一樣,但當使用修飾符m時,它們不會多次匹配,而^$將在每個內部行分隔符處匹配。

預設情況下,.元字元匹配任何字元,但如果關閉修飾符s,則.不會匹配嵌入的行分隔符。

TRegExpr按照Unicode技術標準(技術標準#18)處理行分隔符:

請注意,^.*$(空行模式)不會在\x0D\x0A序列中匹配空字串,但會在\x0A\x0D序列中匹配空字串。

5.2. 元字元 - 預定義類

一些表示式有助於檢測字元組。

預定義類
表示式結果
\w
字母數字字元(包括_),即[0-9A-Za-z_]
\W
非字母數字字元
\d
數字字元
\D
非數字字元
\s
任何空格字元(與[ \t\n\r\f]相同)
\S
非空格字元

您可以在自定義字元類中使用\w\d\s

以下是一些示例:

預定義類示例
表示式結果
foob\dr
匹配像foob1rfoob6r等字串,但不包括foobarfoobbr
foob[\w\s]r
匹配像foobarfoob rfoobbr等字串,但不包括foob=r

5.3. 元字元 - 詞邊界

詞邊界(\b)是在其一側有\w而另一側有\W的兩個字元之間的位置(以任一順序),將字串開頭和結尾的假想字元計為匹配\W

詞邊界
表示式結果
\b
匹配詞邊界
\B
匹配非詞邊界

5.4. 元字元 - 迭代器

正規表示式的任何項目都可以跟隨另一種類型的元字元 – 迭代器。

使用這些元字元,您可以指定前一個字元、元字元或子表示式的出現次數。

迭代器
表示式結果
*
零次或多次("貪婪"),類似於{0,}
+
一次或多次("貪婪"),類似於{1,}
?
零次或一次("貪婪"),類似於{0,1}
{n}
恰好n次("貪婪")
{n,}
至少n次("貪婪")
{n,m}
至少n次但不超過m次("貪婪")
*?
零次或多次("非貪婪"),類似於{0,}?
+?
一次或多次("非貪婪"),類似於{1,}?
??
零次或一次("非貪婪"),類似於{0,1}?
{n}?
恰好n次("非貪婪")
{n,}?
至少n次("非貪婪")
{n,m}?
至少n次但不超過m次("非貪婪")

因此,形式為{n,m}的花括號中的數字指定匹配項目的最小次數n最大次數m

形式{n}等同於{n,n},恰好匹配n次。

形式{n,}匹配n次或更多次。

nm的大小沒有限制,但大數字會減慢執行速度並消耗更多記憶體。

如果花括號出現在任何其他上下文中,它被視為普通字元。

以下是一些示例:

迭代器示例
表示式結果
foob.*r
匹配像foobarfoobalkjdflkj9rfoobr等字串
foob.+r
匹配像foobarfoobalkjdflkj9r等字串,但不包括foobr
foob.?r
匹配像foobarfoobbrfoobr等字串,但不包括foobalkj9r
fooba{2}r
匹配字串foobaar
fooba{2,}r
匹配像foobaarfoobaaarfoobaaaar等字串
fooba{2,3}r
匹配像foobaarfoobaaar等字串,但不包括foobaaaar

關於"貪婪性"的一點解釋。

"貪婪"取盡可能多,"非貪婪"取盡可能少。

例如,b+b*應用於字串abbbbc返回bbbbb+?返回bb*?返回空字串,b{2,3}?返回bbb{2,3}返回bbb

您可以將所有迭代器切換到"非貪婪"模式(參見修飾符g)。

5.5. 元字元 - 替代項

您可以使用|分隔一系列替代項來為模式指定,因此fee|fie|foe將匹配目標字串中的feefiefoef(e|i|o)e也是如此)。

第一個替代項包括從上一個模式分隔符(([或模式開頭)到第一個|的所有內容,最後一個替代項包含從最後一個|到下一個模式分隔符的所有內容。

因此,通常做法是將替代項括在括號中,以最大程度地減少關於它們開始和結束位置的混淆。

替代項從左到右嘗試,因此找到的第一個使整個表示式匹配的替代項將被選擇。

這意味著替代項不一定是貪婪的。

例如:當用foo|foot匹配barefoot時,只有foo部分會匹配,因為這是第一個嘗試的替代項,並且它成功匹配了目標字串。(當我們使用括號捕獲匹配文字時,這可能並不重要。)

還要記住,|在方括號內被解釋為字面意思,因此如果您寫[fee|fie|foe],實際上只匹配[feio|]

示例:

替代項示例
表示式結果
foo(bar|foo)
匹配字串foobarfoofoo

5.6. 元字元 - 子表示式

括號結構( ... )也可用於定義正規表示式子表示式。

搜尋後,您可以調用任何子表示式,還可以將子表示式用作遮罩。

子表示式根據其左括號從左到右的順序進行編號。

第一個子表示式編號為1,最多支援90個子表示式(整個正規表示式匹配編號為0 – 您可以將其替換為$0$&)。

以下是一些示例:

子表示式
表示式結果
(foobar){8,10}
匹配包含8、9或10個foobar實例的字串
foob([0-9]|a+)r
匹配foob0rfoob1rfoobarfoobaarfoobaar

關於"替換為"模板的注意事項:

示例:

讓我們將日期21.01.2018倒置為2018.01.21
  搜尋:(\d{2})\.(\d{2})\.(\d{4})
  替換為:$3.$2.$1

5.7. 元字元 - 反向引用

元字元\1\9被解釋為反向引用。\n匹配先前匹配的子表示式n

以下是一些示例:

反向引用示例
表示式結果
(.)\1+
匹配aaaacc
(.+)\1+
也匹配abab123123
(['"]?)(\d+)\1
匹配"13"(雙引號中)、'4'(單引號中)或77(無引號)等

6. 斷言(前瞻和後瞻斷言)

正向前瞻斷言:foo(?=bar)僅在bar之前匹配foo,並且bar不包含在匹配中。

負向前瞻斷言:foo(?!bar)僅在後面不跟bar時匹配foo

正向後瞻斷言:(?<=foo)bar僅在foo之後匹配bar,並且foo不包含在匹配中。

負向後瞻斷言:(?<!foo)bar僅在前面沒有foo前綴時匹配bar

限制:

7. 非捕獲組

語法:(?:expr)

這種組沒有"索引",對反向引用不可見。當我們想要對子表示式進行分組,但不想將其儲存為字串的匹配/捕獲部分時,使用非捕獲組。使用非捕獲組可以加快正規表示式的工作速度。

非捕獲組
表示式結果
(https?|ftp)://([^/\r\n]+)
https://doublecmd.sourceforge.io中匹配httpsdoublecmd.sourceforge.io
(?:https?|ftp)://([^/\r\n]+)
https://doublecmd.sourceforge.io中僅匹配doublecmd.sourceforge.io

8. 原子組

語法:(?>expr|expr|...)

原子組是非捕獲組的特殊情況:如果模式的一部分已經找到,這種分組會禁用括號組的回溯。原子組工作更快,對於優化具有許多不同表示式的組很有用。

例如,a(bc|b)c匹配abccabca(?>bc|b)c匹配abcc但不匹配abc,因為引擎被禁止回溯並嘗試將組設定為b

9. Unicode類別

Unicode標準為字元類別命名。這些是2字母字串。例如Lu是大寫字母,Ll是小寫字母。而1字母的大類別L是所有字母。

Unicode類別
類別描述
L
字母
Lu
大寫字母
Ll
小寫字母
Lt
標題大小寫字母
Lm
修飾符字母
Lo
其他字母
M
標記
Mn
非間距標記
Mc
間距組合標記
Me
封閉標記
N
數字
Nd
十進位數字
Nl
字母數字
No
其他數字
P
標點符號
Pc
連接符標點
Pd
連字號標點
Ps
開標點
Pe
閉標點
Pi
初始標點
Pf
末尾標點
Po
其他標點
S
符號
Sm
數學符號
Sc
貨幣符號
Sk
修飾符符號
So
其他符號
Z
分隔符
Zs
空格分隔符
Zl
行分隔符
Zp
段落分隔符
C
其他
Cc
控制
Cf
格式
Cs
代理
Co
私有使用
Cn
未分配

元字元\p表示指定類別的一個Unicode字元。語法:\pL\p{L}用於1字母名稱,\p{Lu}用於2字母名稱。

元字元\P是反向的,它表示不在指定類別中的一個Unicode字元。

這些元字元在字元類中也受支援。

10. 修飾符

單個修飾符的語法:(?i)表示打開,(?-i)表示關閉。允許多個修飾符,如:(?msgxr-imsgxr)

修飾符用於更改正規表示式的行為。修飾符僅影響(?imsgxr-imsgxr)運算子之後的正規表示式部分。

這些修飾符中的任何一個都可以嵌入到正規表示式本身中。如果修飾符內聯到子表示式中,則它僅影響該子表示式。

i
執行不區分大小寫的模式匹配(使用系統中安裝的區域設定)。預設關閉。
m
將字串視為多行。即,將^$從僅匹配字串的開頭或結尾更改為匹配字串內任何行的開頭或結尾,另請參見行分隔符。預設關閉。
s
將字串視為單行。即,將.更改為匹配任何字元,甚至是行分隔符(另請參見行分隔符),而它通常不會匹配。預設打開。
g
非標準修飾符。關閉它將把所有後續運算子切換到非貪婪模式(預設情況下此修飾符打開)。因此,如果修飾符g關閉,則+的工作方式為+?*的工作方式為*?等。
x
通過允許空格和註釋來擴展模式的可讀性(見下文說明)。預設關閉。
r
非標準修飾符。如果設定,則範圍а-я額外包括俄語字母ёА-Я額外包括Ёа-Я包括所有俄語字母。預設打開。
#
(?#text):註釋,text被忽略。請注意,TRegExpr在看到)時關閉註釋,因此無法在註釋中放入字面)

以下是一些示例:

Perl擴展示例
表示式結果
(?i)Saint-Petersburg
匹配Saint-petersburgSaint-Petersburg
(?i)Saint-(?-i)Petersburg
匹配Saint-Petersburg但不匹配Saint-petersburg
(?i)(Saint-)?Petersburg
匹配Saint-petersburgsaint-petersburg
((?i)Saint-)?Petersburg
匹配saint-Petersburg但不匹配saint-petersburg

修飾符x本身需要更多的解釋。

它告訴忽略既不帶反斜線也不在字元類中的空格。

您可以使用它將正規表示式分解為(稍微)更可讀的部分。

#字元也被視為引入註釋的元字元,例如:

(
  (abc) # 註釋1
    |   # 您可以使用空格來格式化正規表示式 - TRegExpr會忽略它
  (efg) # 註釋2
)

這也意味著如果您想在模式中使用真正的空格或#字元(在字元類之外,它們不受x影響),您必須跳脫它們或使用八進位或十六進位跳脫進行編碼。

總的來說,這些功能大大提高了正規表示式文字的可讀性。


有效的HTML 4.0過渡 CSS有效!