1 回答
TA貢獻1851條經驗 獲得超4個贊
首先你這個例子中的匹配表達式也太長了,匹配個日期根本不需要這么麻煩,不建議糾結這個表達式,可以找到更好的正則寫法,我就你的兩點問題做一個回答吧。
1.簡單來說,(?:)就是為了分組,但是不捕獲下來供正則表達式其他部分使用,就是說不能使用\1,\2這種捕獲的子模式。
舉個例子
var pattern1=/aacdaa/;
var pattern2=/(?:aa|bb)cd\1/;
var pattern3=/(aa|bb)cd\1/;
var str="aacdaa";
console.log(str.match(pattern1)); // ["aacdaa", index: 0, input: "aacdaa"]
console.log(str.match(pattern2)); // null
console.log(str.match(pattern3)); // ["aacdaa", "aa", index: 0, input: "aacdaa"]
第一個匹配到了,沒問題,普通的匹配
第二個就沒匹配到,因為\1在這里無法識別,是非獲取匹配
第三個就匹配到了,因為()是獲取性匹配,看后面的輸出 數組中第二項是aa,匹配了這個子模式,可以供后續使用,后面的\1就是匹配到的子模式aa。
所以說(?:)的作用就是為了分組,它和()的區別在上面這個例子中已經表現出來了,至于它和普通模式的區別,就體現在分組的便利上。
上面的例子改一下:
var pattern4=/aacd|bbcd/;
var pattern5=/(?:aa|bb)cd/;
兩種寫法是一樣的匹配模式,但是用了分組之后,簡潔了不少,這就是非獲取匹配的最常用的作用
2.(?!p)是負向先行斷言,意思是要求接下來的字符不與p表達式匹配,,還有一個(?=p)也一塊說了吧,這個正好和?!相反,稱為正向先行斷言,要求接下來的字符與p表達式匹配。也就是說這里的(?:)和(?!)起的就是一個條件作用,用來判斷前面的表達式滿足不滿足p這個條件,只有滿足了才匹配,不滿足就不匹配。
同樣用上面類似的例子來說明:
var pattern6=/aa(?=cd)/;
var pattern7=/aa(?!cd)/;
var s1="aacd";
var s2="aabb";
console.log(s1.match(pattern6),s1.match(pattern7));//["aa", index: 0, input: "aacd"] , null
console.log(s2.match(pattern6),s2.match(pattern7));//null , ["aa", index: 0, input: "aabb"]
s1匹配了pattern6,因為s1中的aa后面接著的是cd,s2匹配了pattern7,因為s1中的aa后面接著的不是cd。
添加回答
舉報
