如何使用正則表達(dá)式表示「非」邏輯?
'^' 可以表示排除的邏輯:
[^abc] # 除abc之外的所有字符
然而這個(gè)簡(jiǎn)單的表示符號(hào)并不總是有效果的??紤]這樣的需求:匹配后綴名不為 '.jpg' 的字符串。使用 '^'是無法滿足需求的。
正則表達(dá)式還有一個(gè)非常有用的功能——環(huán)視(lookaroud)。
環(huán)視包括順序環(huán)視(lookahead)和逆序環(huán)視(lookbehind);每種又分為肯定和否定兩種。利用環(huán)視可以為我們本想匹配的部分設(shè)置一個(gè)特定的「環(huán)境」。
(?=...) positive lookahead: Matches if ... matches next, but doesn't consume the string.
(?!...) negative lookahead: Matches if ... doesn't match next.
(?<=...) posttive lookbehind: Matches if preceded by ... (must be fixed length).
(?<!...) negative lookbehind: Matches if not preceded by ... (must be fixed length).
環(huán)視類似于一條斷言,從當(dāng)前位置的字符開始匹配環(huán)視表達(dá)式,如果匹配成功,則會(huì)從環(huán)視表達(dá)式匹配到的開始位置繼續(xù)匹配后續(xù)的正則表達(dá)式,否則本次匹配失敗。
例子??:
pattern = '^((?!\.jpg$).)+$' 表示不以 '.jpg' 結(jié)尾的所有字符串。
在這個(gè)例子中,^.+$ 是我們真正想匹配的模式,當(dāng)加上前面的環(huán)視表達(dá)式 (?!\.jpg$) 的時(shí)候,會(huì)在每次匹配開始之前,先先匹配環(huán)視表達(dá)式里指定的模式,因?yàn)槲覀冇玫氖恰疙樞蚍穸ā沟沫h(huán)視表達(dá)式,所以會(huì)從當(dāng)前位置向后匹配,期待環(huán)視表達(dá)式匹配失敗。這里的這條環(huán)視表達(dá)式的意思是「從當(dāng)前位置開始,不能以 .jpg 作為結(jié)束」。
例子??:
pattern = '(?<![\d,])(\d{1,3}(,\d{3})*)(?![\d,]) 表示從右往左每三位數(shù)字由一個(gè)逗號(hào)隔開的數(shù)字。
用上面的例子,可以從一段字符串中,匹配到符合上述要求的格式的數(shù)字。主要使用了2個(gè)環(huán)視表達(dá)式去限定數(shù)字模式所處的「環(huán)境」。(?![\d,]) 是一個(gè)順序的否定環(huán)視,他表示從當(dāng)前位置開始,向右匹配數(shù)字或者逗號(hào),并且期待匹配失敗。如此限定了,已匹配的數(shù)字模式右邊不能有數(shù)字或者逗號(hào)。?<![\d,] 同樣,不過他是從當(dāng)前位置開始,從右往左匹配,同樣限制了已匹配的數(shù)字模式左邊不能有數(shù)字或者逗號(hào)。
除以上2個(gè)簡(jiǎn)單的例子,環(huán)視表達(dá)式還有其他有用的途徑。
理解的關(guān)鍵在于:環(huán)視表達(dá)式是一個(gè)預(yù)匹配,它不會(huì)占用匹配位置;它是從指定了環(huán)視表達(dá)式的位置開始匹配,可以向左也可以向右;它的期待結(jié)果可以是成功,也可以是失敗。
關(guān)鍵的一個(gè)用途是,限定想匹配的模式的「環(huán)境」。
參考