[英]How does this pattern match hyphen without escape?
經過regex101幾分鍾后,我意識到,如果立即跟隨[
]
則不需要逃脫。
在regex101中 ,模式[]-az]
描述為
/[]-az]/ []-az] match a single character present in the list below ]-aa single character in the range between ] and a (case sensitive) -za single character in the list -z literally (case sensitive)
但是我一直認為,如果-
必須從字面上進行匹配而又不能逃脫,則它應該在開頭或結尾處使用 。
那為什么我的模式不被識別為錯誤 ? 為什么-z
匹配列表中的一個字符-z
字面上?
讓我們分解一下:
[]-a-z]
^^ ^
|| +---- 3
|+------ 2
+------- 1
1
是文字]
因為它出現在模式的開頭,而[]
是PCRE中的無效字符類。
因此, 2
連字符是該類中的第二個字符,並在]
和a
之間引入了一個范圍。
從字面上看下一個連字符3
,因為前一個標記a
是前一個范圍的結尾。 此時無法引入其他范圍。 在PCRE中,如果-
位於無法引入范圍的地方或逃脫了,則按字面意義對待。 我們通常在范圍的開頭或結尾放置文字連字符以使其變得明顯,但這不是必需的。
那么, z
是一個簡單的文字。
PCRE遵循Perl語法。 記錄如下:
[關於]
:
]
通常是POSIX字符類的結尾(請參見下面的POSIX字符類),或者它表示括號中的字符類的結尾。 如果要在字符集中包含[]
,則通常必須對其進行轉義。
然而,如果]
是所述第一 (或第二,如果第一字符是脫字符號)一個括號字符類的字符,它不表示類的端部(如你不能有一個空類)和被認為是部分無需轉義即可匹配的字符集。
關於連字符:
如果字符類中的連字符不能從句法上成為范圍的一部分 ,例如因為它是字符類的第一個字符或最后一個字符, 或者它緊隨范圍 ,則該連字符不是特殊字符,因此被視為要從字面上進行匹配的字符。 如果要匹配字符集中的連字符,並且其在類中的位置可以被認為是范圍的一部分,則必須使用反斜杠對連字符進行轉義。
請注意,這是指Perl語法。 其他口味可能具有不同的行為。 例如, []
是JavaScript中有效的(空)字符類,不能匹配任何內容。
問題是,根據選項的不同,PCRE還可以用JS方式(有幾個JS兼容性標志)來解釋這一點。 從PCRE2文檔 :
右方括號引入了一個字符類,並以右方括號終止。 默認情況下,右方括號本身並不特殊。 如果需要使用方括號作為類的成員,則該方括號應為類中的第一個數據字符(如果有初始抑揚符號,則應在后面)或以反斜杠轉義。 這意味着默認情況下無法定義空類。 但是,如果設置了
PCRE2_ALLOW_EMPTY_CLASS
選項,則PCRE2_ALLOW_EMPTY_CLASS
方括號確實會終止(空)類。
毫無疑問,已記錄的有關連字符的PCRE行為與Perl行為匹配:
減號(連字符)可用於指定字符類中的字符范圍。 例如,
[dm]
匹配d和m之間的任何字母(包括首尾)。 如果類中需要減號,則必須用反斜杠將其轉義或出現在無法解釋為指示范圍的位置 ,通常是類中的第一個或最后一個字符,或緊接在范圍之后。 例如,[bdz]
匹配b
到d
范圍內的字母,連字符或z
。
正則表達式不會失敗,因為-
表示此處的范圍是從]
到a
。 ]
不必在字符類內部的起始位置轉義,因此在此處被視為文字。 字符類有效,因為]
在ASCII表中具有93
ASCII碼,而a
具有97
碼。
編輯:
關於正則表達式有一件事是通用的:它們是從左到右進行分析的。 因此,使用第一連字符周圍的第一字符形成范圍。 第二連字符位於范圍結束字符之后,並且不能用作起始范圍字符,因為它已被“占用”。 因此,正則表達式引擎只能將第二個連字符解析為文字
請參閱PCRE參考 :
減號(連字符)可用於指定字符類中的字符范圍。 例如,[dm]匹配d和m之間的任何字母(包括首尾)。 如果類中需要減號,則必須用反斜杠將其轉義或出現在無法解釋為指示范圍的位置,通常是類中的第一個或最后一個字符,或緊接在范圍之后。 例如,[bdz]匹配b到d范圍內的字母,連字符或z。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.