正則表達式順序
回答
當教程介紹lookarounds,他們往往會選擇每一個最簡單的使用情況。因此,他們會使用(?<!a)b
('b''之前未加'a')或q(?=u)
('q'後加'u')的示例。這只是爲了避免讓注意力分散的細節混淆解釋,但它傾向於創造(或加強)這樣的印象,即往後看和向後看起來應該以某種順序出現。我花了相當長的時間來克服這個想法,而且我也看到其他幾個人也受到了這個問題的困擾。
試着看一些更實際的例子。一個涉及很多問題涉及驗證密碼;例如,確保新密碼長度至少爲六個字符並且至少包含一個字母和一個數字。要做到這一點的方法之一是:
^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{6,}$
的字符類[A-Za-z0-9]{6,}
可以匹配所有字母或所有數字,讓你用的向前看符號,以確保有各自的至少一個。在這種情況下,您必須首先執行,因爲正則表達式的後面部分必須能夠檢查整個字符串。
又例如,假設您需要查找單詞「there」的所有出現位置,除非其前面帶有引號。顯而易見的正則表達式是(?<!")[Tt]here\b
,但是如果您搜索的是大型語料庫,那可能會造成性能問題。正如所寫的那樣,該正則表達式將在文本中的每一個位置都做負面的後臺關係,並且只有當它成功時纔會檢查正則表達式的其餘部分。
每一個正則表達式引擎都有自己的長處和短處,但其中的一點是,它們更快地找到文字字符的固定序列,而不是其他任何東西 - 序列越長越好。這意味着它可以大大加快做回顧後最後,即使這意味着這個詞兩次匹配:
[Tt]here\b(?<!"[Tt]here)
所以管理lookarounds的位置,規則是沒有規則;你把它們放在最有意義的地方。
1(?=ABC)
表示 - 查找1
,並且匹配(但不捕獲)後面的ABC
。
(?<=ABC)1
表示在當前位置之前匹配(但不捕獲)ABC
,並繼續匹配1
。
因此,通常情況下,您會在前面的表達式和後面的後面放置向前看。
當我們在表達式後面放置一個倒序時,我們正在重新檢查我們已經匹配的字符串。當你有複雜的條件時,這很常見(你可以把它想象成AND
的正則表達式)。例如,拿在最近這次的回答看看由Daniel Brückner:
.&.(?<! &)
首先,你捕獲兩個字符之間的符號。接下來,你檢查他們是不是空格(\S&\S
不會在這裏工作,OP想要捕獲1&_
)。
我覺得在示例中比解釋更容易。讓我們這個表達式:
(?<=\d)(?=(.)\1)(?!p)\w(?<!q)
這意味着:
(?<=\d)
- 確保賽前位置是一個數字會發生什麼。(?=(.)\1)
- 確保我們在這個(相同)位置匹配的任何字符後面跟着一個自身副本(通過反向引用)。(?!p)
- 確保接下來不是p
。\w
- 匹配字母,數字或下劃線。請注意,這是我們第一次真正匹配並使用角色。(?<!q)
- 確保我們迄今爲止匹配的內容不會以q
結尾。
所有這一切都將匹配像abc5ddx
或9xx
但不5d
或6qq
或asd6pp
或add
字符串。請注意,每個斷言獨立工作。它只是停下來,環顧四周,如果一切順利的話,讓匹配繼續下去。
還要注意的是,在大多數(可能全部)實現中,lookbehinds具有固定長度的限制。您不能在其中使用重複/可選性運算符,如?
,*
和+
。這是因爲要匹配一個模式,我們需要一個起點 - 否則我們必須嘗試匹配字符串中每個點的每個後視圖。
此正則表達式的串a3b5ddx
的樣品運行如下:
- 文本光標位置:0
- 嘗試第一回顧後在位置匹配-1(因爲
\d
總是匹配1個字符)。我們不能匹配負指數,所以失敗並提前光標。
- 嘗試第一回顧後在位置匹配-1(因爲
- 文本光標位置:1.
- 嘗試匹配位置0
a
第一回顧後不匹配\d
如此失敗,再次向前移動光標。
- 嘗試匹配位置0
- 文本光標位置:2
- 嘗試在第一回顧後在位置1
3
匹配不匹配\d
所以保持光標不變,並且繼續匹配。 - 嘗試匹配位置2處的第一個預測。
b
匹配(.)
並被捕獲。5
不匹配\1
(這是被捕獲的b
)。因此,失敗並推進遊標。
- 嘗試在第一回顧後在位置1
- 文本光標位置:3
- 嘗試匹配在2位
b
第一回顧後不匹配\d
如此失敗,再次向前移動光標。
- 嘗試匹配在2位
- 文本光標位置:4
- 嘗試在第一回顧後在位置3
5
匹配不匹配\d
所以保持光標不變,並且繼續匹配。 - 嘗試匹配位置4處的第一個預測。
d
匹配(.)
並被捕獲。第二個d
確實匹配\1
(這是第一個捕獲的d
)。允許匹配從我們離開的地方繼續。 - 嘗試匹配第二個預測。在位置4處的
b
與p
不匹配,並且由於這是負向前視,所以我們想要;允許匹配繼續。 - 嘗試匹配
\w
的第4位。b
比賽。由於我們已經消耗了一個字符並繼續,因此前進光標同樣將此標記爲比賽的開始。
- 嘗試在第一回顧後在位置3
- 文本光標位置:5.
- 嘗試匹配在第4位的第二回顧後(因爲
q
總是匹配1個字符)。d
不符合q
這是我們想要從負面看後面。 - 意識到我們處於正則表達式的末尾,並通過將匹配字符串從當前位置(4到5)返回到
d
來報告成功。
- 嘗試匹配在第4位的第二回顧後(因爲
- 1. 正則表達式查詢的順序
- 2. 正則表達式匹配順序
- 3. 正則表達式 - 不介意順序?
- 4. 正則表達式(正則表達式)
- 5. 正則表達式(正則表達式)
- 6. 正則表達式(正則表達式)
- 7. 正則表達式:序列
- 8. 正則表達式以任意順序匹配多個模式
- 9. java正則表達式多種模式順序匹配
- 10. 按順序匹配正則表達式模式
- 11. 正則表達式模式匹配5個在增量順序
- 12. 正則表達式捕獲順序:貪婪模式
- 13. 正則表達式模式匹配順序
- 14. 正則表達式的排序順序相反
- 15. 正則表達式不按升序順序運行。
- 16. 正則表達式正則表達式正則表達式使用正則表達式,但不是與Python
- 17. 正則表達式,按字母順序排列URL的列表?
- 18. 正則表達式顛倒順序的列表?
- 19. 正則表達式正則表達式返回的值正則表達式
- 20. 正則表達式正則表達式模仿正則表達式
- 21. PHP-MySQLi替換爲正則表達式/正則表達式/正則表達式
- 22. 正則表達式幫助,如何使表達式的順序無關緊要?
- 23. 正則表達式表達
- 24. 正則表達式表達
- 25. 正則表達式表達
- 26. 正則表達式Java中的黑角...字符順序改變了正則表達式的含義?
- 27. 正則表達式:錯誤 - 無效的正則表達式「系列出的順序字符類」
- 28. 在正則表達式中,字符類中的字符順序是否正則表達式
- 29. 正則表達式來查找不同順序的單詞
- 30. 順序處理算法或正則表達式
'[^]&[^]'可能比'。&。(?<!&)'更容易理解。 – Gumbo 2010-01-24 09:30:12
這將不會匹配「this&that」,而lookbehind版本會。一個有效的等價物應該是:'\ S&|&\ S' – 2010-01-24 09:47:09