1 /** 2 * 直接量字符(這個沒有舉例子) 3 * 4 * 字母和數字字符 匹配自身 5 * \o NUL字符(\u0000),\t制表符(\u0009),\n換行符(\u000A) 6 * \v垂直制表符(\u000B),\f換頁符(\u000C),\r回車符(\u000D) 7 * \xnn由十六進制數nn指定的拉丁字符,如:\x0A等價於\n 8 * \uxxxx由十六進制數xxxx指定的Unicode字符,如:\0009等價於\t 9 * \cX控制字符^X,如:\cJ等價於換行符\n 10 */ 11 12 13 /** 14 * 字符類: 將直接量字符放進方括號內“[]”,就組成了字符類,一個字符類匹配它所包含的任意字符 15 * 16 * [...] 方括號內任意字符 , [^...] 不在方括號內任意字符 17 * . 除換行符和其他Unicode行終止符之外的任意字符 18 * \w 任何ASCII字符組成的單詞 等價於[a-zA-Z0-9],\W 與 \w 相反 等價於 [^a-zA-Z0-9] 19 * \s 任何Unicode空白符,\S 與 \s 相反 20 * \d 任何ASCII數字,\D 與 \d 相反 21 * [\b] 退格直接量 22 */ 23 console.log("e2ba53w".match(/\S/g));//輸出 [ 'e', '2', 'b', 'a', '5', '3', 'w' ] 24 //可通過"^"符號來定義否定字符類,它匹配所有不包含在方括號內的字符。注意,在定義否定字符類時, 25 //需要將"^"符號作為左方括號內的第一個字符 26 console.log("ebaw".match(/[^abc]/g));//輸出 [ 'e', 'w' ] 27 28 29 /** 30 * 重復字符(原則:盡可能多地匹配 “貪婪”匹配) 31 * 32 * {n,m} 匹配前一項至少n次但不超過m次, 33 * {n,} 匹配前一項n次或更多次 34 * {n} 匹配前一項n次, 35 * ? 匹配前一項0次或1次,即{0,1} 36 * + 匹配前一項1次或多次,即{1,} , 37 * * 匹配前一項0次或多次,即{0,} 38 */ 39 //“非貪婪”匹配,在待匹配的字符后跟一個"?"號即可 "??","+?","*?","{1,9}?" 40 // 正則表示式: "aaab".match(/a+b/) 匹配結果 "aaab",而不是 "ab" 41 // 因為正則表達式的模式匹配總是會尋找字符串中第一個可能的匹配位置 42 43 /** 44 * 選擇、分組、引用 45 */ 46 // "|" 用於分隔供選擇的字符,匹配順序從到右直到發現匹配項,若左邊的選擇項匹配,則忽略右邊的選擇項匹配 47 console.log("a3b45fd".match(/\d{2}|[a-z]{3}/));//輸出:"45" ,匹配2個數字或3個字母 48 49 //圓括號 50 //作用一:把單獨的項組合成子表達式,以便可以像處理一個獨立的單元那樣進行處理 51 //如:/(java)+(script)?/ 52 53 //作用二:在完整的模式中定義子模式,當一個正則成功地和目標字符串匹配時,可以從目標串中抽出圓括號中的子模式想匹配的部分 54 //如下面執行結果為:輸出:[ '123abc666', '123', 'abc', '666', index: 0, input: '123abc666' ] 55 console.log("123abc666".match(/([0-9]*)([a-z]+)(666)/)); 56 57 //作用三:允許正則表達式的后部引用前面的子表達式,通過字符"\"后加一位或多位數字實現 58 //如:對 /([jJ]ava([Ss]cript)?)\sis\s(fun\w*)\s\2/ 來說,"\2" 指代 ([Ss]cript)所匹配的文本的引用 59 console.log("javascript is fun script".match(/([jJ]ava([Ss]cript)?)\sis\s(fun\w*)\s\2/)); 60 //輸出:[ 'javascript is fun script','javascript','script','fun',index: 0,input: 'javascript is fun script' ] 61 //解析:([Ss]cript) 在正則中匹配的是 'script' ,因此 \2 也匹配 'script' 62 63 //注:對正則表達式中前一個表達式的引用,並不是對子表達式模式的引用,而是指與那個模式相匹配的文本的引用,不能再字符類中使用 64 //如:/['"][^'"]*['"]/ 不要求左側引號和右側引號匹配,字符串 'fd3" 可以正確匹配 65 console.log(" 'fd3\" ".match(/['"][^'"]*['"]/));//輸出:'fd3" 66 //如:/['"][^'"]*\1/ 由於 \1 “是指與那個模式相匹配的文本的引用” ,如果前面匹配的文本為單(雙)引號 '(") ,那么后面也要匹配單(雙)引號 '(") , 67 console.log(" 'fd3\" ".match(/(['"])[^'"]*\1/));//輸出:null 68 console.log(" 'fd3' ".match(/(['"])[^'"]*\1/));//輸出:'fd3' 69 //如:/['"][^\1]*\1/ 非法,不能再字符類中使用 70 71 //不想創建帶有數字編碼的引用,也可以對子表達式進行分組 72 //如:對 /([jJ]ava(?:[Ss]cript)?)\sis\s(fun\w*)/ 來說, "\2" 指代 (fun\w*) 73 74 75 /** 76 * 指定匹配位置 正則表達式中的錨字符(匹配的是正則表達式之間的位置,不匹配實際的字符) 77 * ^ 匹配字符串的開頭,多行檢索中匹配一行的開頭 78 * $ 匹配字符串的結尾,多行檢索中匹配一行的結尾 79 * \b 匹配一個單詞的邊界(即 \w和\W之間的位置,或位於字符\w和字符串的開頭或結尾的位置,匹配的是退格符) 80 * \B 與\b相反,匹配非單詞邊界的位置 81 * (?=p) 零寬正向先行斷言,要求接下來的字符都與p匹配,但不能包括匹配p的哪些字符 82 * (?!p) 零寬負向先行斷言,要求接下來的字符不與p匹配 83 */ 84 //如匹配單詞"javascript" 85 console.log("javascript".match(/^javascript$/));//輸出:"javascript" 86 //如 /\b[jJ]ava\b/ 匹配 "java"、" java"、"java ",不匹配"abcjava"或"javaabc" 87 console.log(" java".match(/\bjava\b/));//輸出:"java" 88 //如 /\B[Jj]ava/ 匹配 "abcjava",不匹配"java"或"javaabc"或" java" 89 console.log("abcjava".match(/\Bjava/));//輸出:"java" 90 91 //正向先行斷言 92 //如: /[Jj]ava([Ss]cript)?(?=\:)/ 要求 j(J)avas(S)cript 接下來的字符必須是冒號 : ,但匹配的結果不包括冒號 93 console.log("JavaScript: The Definitive Guide".match(/[Jj]ava(?:[Ss]cript)?(?=\:)/));//輸出:JavaScript 94 console.log("Java The Definitive Guide".match(/[Jj]ava([Ss]cript)?(?=\:)/));//輸出:null 95 96 //負向先行斷言 97 //如:/Java(?!Script)([A-Z]\w*)/ 要求 j(J)avas(S)cript 接下來的字符必須不能是字符串 Script 98 console.log("JavaScriptAbc".match(/Java(?!Script)([A-Z]\w*)/));//輸出:null 99 console.log("JavaBeans".match(/Java(?!Script)([A-Z]\w*)/));//輸出:JavaBeans 100 101 102 /** 103 * 修飾符 104 * 修飾符放在 “//”符號之外,在第二條斜線之后 105 * i 執行不區分大小寫的匹配 106 * g 執行一個全局匹配,即找出被檢索字符串的所有匹配項 107 * m 多行匹配模式,即如果檢索字符串包含多行,^和$處理匹配整個字符串的開始和結尾 108 * 還能匹配每一行的開始和結尾 109 */ 110 //如:/java$/im , i忽略大小寫,m匹配多行 111 console.log("Java\n is fun"); 112 /** 113 * 輸出: 114 * Java 115 * is fun 116 */ 117 118 119 /** 120 * 用於模式匹配的String方法: 121 * search()最簡單,不支持全局 122 * replace()很強大,默認不全局搜索 123 * match()最常用,默認不全局搜索 124 * split() 125 * 這些方法是 String.prototype 的方法,只不過它們支持正則表達式而已 126 */ 127 128 129 //search(),返回正則表達式在字符串中首次匹配項的索引。否則,返回 -1。參數是正則表達式,若參數不是正則則先轉換成正則 130 console.log("javascript".search(/script/i));//輸出:4 131 console.log("javascript".search("script"));//輸出:4 132 133 //replace(),替換操作 134 //參數一:正則或字符串 參數二:替換字符串(還可以是函數),($$:插入一個:"$"),($&:插入匹配的子串),($`[反引號]:插入當前匹配的子串左邊的內容), 135 //($':插入當前匹配的子串右邊的內容),($n:若參數一是 RegExp對象且 0<n<100 那么就插入正則表達式中第 n 個括號最近一次匹配結果中的內容) 136 137 //參數一:字符串 138 var str="hello world,how are you?" 139 console.log(str.replace("world","guang"));//hello guang,how are you? 140 141 //參數一:正則表達式 142 var str='"cat", "bat", "sat", "fat"'; 143 console.log(str.replace(/"([^"]*)"/g,"Hello “$1”")); 144 // 輸出: Hello “cat”, Hello “bat”, Hello “sat”, Hello “fat” 可以看到 ""(英文符號) 變成了 “”(中文符號) 145 // 解析: 對於上述字符串來說: 146 // 正則表達式 /"([^"]*)"/g 的匹配結果為: ("cat" "bat" "sat" "fat") 147 // 那 /"([^"]*)"/g 括號中的的匹配結果就為:( cat bat sat fat ) 148 // $1 :表示要插入正則表達式中第 1 個括號最近一次匹配結果中的內容(分別為: cat bat sat fat ) 149 // Hello “$1” :就可以看出表示的是 (Hello “cat” Hello “bat” Hello “sat” Hello “fat”) 150 // 因此就將 ("cat" "bat" "sat" "fat") 替換成了 (Hello “cat” Hello “bat” Hello “sat” Hello “fat”) 151 /** 152 * 對應的還有其他結果: 153 * console.log(str.replace(/"([^"]*)"/g,"Hello “$$”")); 154 * 輸出:Hello “$”, Hello “$”, Hello “$”, Hello “$” 155 * 156 * console.log(str.replace(/"([^"]*)"/g,"Hello “$&”")); 157 * Hello “"cat"”, Hello “"bat"”, Hello “"sat"”, Hello “"fat"” 158 * 159 * console.log(str.replace(/"([^"]*)"/g,"Hello “$`”")); 160 * 輸出:Hello “”, Hello “"cat", ”, Hello “"cat", "bat", ”, Hello “"cat", "bat", "sat", ” 161 * 162 * console.log(str.replace(/"([^"]*)"/g,"Hello “$'”")); 163 * 輸出:Hello “, "bat", "sat", "fat"”, Hello “, "sat", "fat"”, Hello “, "fat"”, Hello “” 164 */ 165 166 //第二個參數是函數的情況:
//參數一:match,匹配的子串(對應於上述的$&)
//參數二:p1,p2, ... 假如replace()方法的第一個參數是一個RegExp 對象,則代表第n個括號匹配的字符串。(對應於上述的$1,$2等)
//參數三:offset 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是“abcd”,匹配到的子字符串是“bc”,那么這個參數將是1)
//參數四:string 被匹配的原字符串。
167 function replacer(match, p1, p2, p3, offset, string) { 168 console.log(match);// 匹配到字符串 abc12345#$*% 169 console.log(offset);// 匹配到的子字符串在原字符串中的偏移量 3 170 console.log(string);// 原字符串 123abc12345#$*%A 171 console.log(p1,p2,p3);// p1、p2、p3 的值 abc 12345 #$*% 172 return [p1, p2, p3].join(' - ');// 返回值 abc - 12345 - #$*% 173 } 174 var newString = '123abc12345#$*%A'.replace(/([^\d]{1,})(\d*)([^\w]*)/, replacer); 175 console.log(newString); // 123abc - 12345 - #$*%A 176 //解析:replacer 返回一個新的替換后的字符串,該方法並不改變調用它的字符串本身 177 //即將 123abc12345#$*%A 想要替換的部分(abc12345#$*%) 替換成 abc - 12345 - #$*% 178 //即 (括號內容將要被替換)(123abc12345#$*%)A ---> (括號內容已經被替換)(123abc - 12345 - #$*%)A 179 180 181 //match(),唯一的參數是正則,如果字符串匹配到了表達式,會返回一個數組,數組的第一項是進行匹配的那個字符串, 182 //之后的項是用圓括號捕獲的結果。如果沒有匹配到,返回null。 183 //Array[1]存放與第一個用圓括號括起來的表達式相匹配的子串,以此類推 184 //為了與replace()保持一致,Array[n]存放的是$n的內容 185 str="Visit my blog at http://www.example.com/~guang"; 186 var result=str.match(/(\w+):\/\/([\w.]+)\/(\S*)/); 187 console.log(result[0],result[1],result[2],result[3]);//http://www.example.com/~guang , http , www.example.com , ~guang 188 189 190 //split(),使用指定的分隔符字符串將一個String對象分割成字符串數組並返回 191 //參數一(可選):分隔符(字符串或正則表達式) 參數二(可選):一個整數,限定返回的分割片段數量 192 //描述:找到分隔符后,將其從字符串中刪除,並將子字符串的數組返回。 193 194 //如果分隔符為空字符串,則將str轉換為字符數組 195 var str="ni hao"; 196 console.log(str.split(""));//[ 'n', 'i', ' ', 'h', 'a', 'o' ] 197 198 //如果分隔符出現在字符串的開始或結尾,則分別以空字符串開頭,結尾。 199 //因此,如果字符串僅由一個分隔符實例組成,則該數組由兩個空字符串組成。 200 var str="#a***b#c*d###e*"; 201 console.log(str.split("#"));//[ '', 'a***b', 'c*d', '', '', 'e*' ] 202 console.log(str.split("*"));//[ '#a', '', '', 'b#c', 'd###e', '' ] 203 console.log("@".split("@"));//[ '', '' ] 204 205 //如果沒有找到或者省略了分隔符,則該數組包含一個由整個字符串組成的元素。 206 var str="hello world"; 207 console.log(str.split("a"));//[ 'hello world' ] 208 console.log(str.split());//[ 'hello world' ] 209 210 //當字符串為空時,split()返回一個包含一個空字符串的數組,而不是一個空數組 211 console.log("".split("separator"));//[ '' ] 212 console.log("".split());//[ '' ] 213 //console.log("".split());也可理解為,如果沒有找到或者省略了分隔符,則該數組包含一個由整個字符串組成的元素。 214 215 //如果字符串和分隔符都是空字符串,則返回一個空數組 216 console.log("".split(""));//[] 217 218 //其他例子,去除空白字符 219 var str="1,2 ,3, 4 , 5"; 220 console.log(str.split(/\s*,\s*/));//輸出:[ '1', '2', '3', '4', '5' ] 221 //解析:console.log(str.match(/\s*,\s*/g));//[ ',', ' ,', ', ', ' , ' ] 222 223 224 /** 225 * RegExp()構造函數 有5個屬性 226 * 只讀屬性: 227 * source 包含正則表達式的文本 228 * global(ignoreCase)(multiline) 用以說明正則是否帶修飾符g(i)(m) 229 * 可讀寫屬性: 230 * lastIndex(這個屬性會被exec()和test()方法用到) 231 * 方法: exec()、test() 232 */ 233 234 //利用RegExp()構造函數創建正則表達式,使用"\"作為專業字符的前綴,因此使用"\"必須替換成"\\" 235 //參數一:正則主體(即//中間的文本),參數二:可選修飾符(i/g/m) 236 //構造函數可用於動態創建正則表達式,如用戶輸入 237 var re=new RegExp("\\d{5}","g"); 238 console.log("123456gww 4321 fjf87654".match(re));//輸出:["12345", "87654"] 239 console.log(re.source,re.global,re.ignoreCase,re.multiline,re.lastIndex);// 輸出:\d{5} true false false 0 240 241 242 //exec()參數是一個字符串,找到則返回一個數組,否則返回null 243 //與match()不同之處在於,exec()不管有無修飾符g"總是返回一個匹配結果" 244 //當它具有修飾符g時,它的lastIndex屬性就為緊挨着匹配子串的字符位置, 245 //當"同一個"正則表達式第二次調用exec()時,則從lastIndex處開始檢索, 246 //找出所有匹配之后lastIndex會自動重置為0 247 //當它不使用全局修飾符g時,每次開始檢索時lastIndex都設置為0 248 249 str="Who think JavaScript is more fun than Java!"; 250 pattern_no_g=/Java/; 251 pattern_carry_g=/Java/g; 252 253 //不使用全局修飾符 254 /* 255 while((result=pattern_no_g.exec(str)) !=null){ 256 console.log("Matched '"+result[0]+"'"+ 257 " at position "+result.index+"; next search " + 258 "begins at "+pattern_no_g.lastIndex); 259 } 260 */ 261 //While循環第一遍返回一個結果:Matched 'Java' at position 10; next search begins at 0 262 //While循環第二遍返回一個結果:Matched 'Java' at position 10; next search begins at 0 263 //...... 死循環 264 //While循環第N遍返回一個結果:Matched 'Java' at position 10; next search begins at 0 265 266 //使用全局修飾符 267 while((result=pattern_carry_g.exec(str)) !=null){ 268 console.log("Matched '"+result[0]+"'"+ 269 " at position "+result.index+"; next search " + 270 "begins at "+pattern_carry_g.lastIndex); 271 } 272 //While循環第一遍返回一個結果:Matched 'Java' at position 10; next search begins at 14 273 //While循環第二遍返回一個結果:Matched 'Java' at position 38; next search begins at 42 274 console.log(pattern_carry_g.lastIndex);//輸出:0,帶有全局修飾符g,找出所有匹配之后,lastIndex自動重置為0 275 276 //只匹配一次(不找出所有匹配) 277 if((result=pattern_carry_g.exec(str)) !=null){ 278 console.log("Matched '"+result[0]+"'"+ 279 " at position "+result.index+"; next search " + 280 "begins at "+pattern_carry_g.lastIndex); 281 } 282 //if條件語句內輸出:Matched 'Java' at position 10; next search begins at 14 283 console.log(pattern_carry_g.lastIndex);//輸出:14,沒有找出所有匹配,因此lastIndex不會自動重置為0 284 var otherStr="JavaScript is fun";//此時 pattern_carry_g.lastIndex 值為 14 285 if((result=pattern_carry_g.exec(otherStr)) !=null){ 286 console.log("Matched '"+result[0]+"'"+ 287 " at position "+result.index+"; next search " + 288 "begins at "+pattern_carry_g.lastIndex); 289 } 290 //輸出:沒有輸出 291 //解析:pattern_carry_g.lastIndex 值為 14,此時檢索將從字符串othertext的othertext[14]開始 292 //因此匹配值為空 result=pattern_carry_g.exec(otherStr) 語句執行后 result 等於 null 293 //因此沒有進入if語句內執行,因此記得必要時應該手動將lastIndex置0 294 295 pattern_carry_g.lastIndex=0;//手動重置為0 296 if((result=pattern_carry_g.exec(otherStr)) !=null){ 297 console.log("Matched '"+result[0]+"'"+ 298 " at position "+result.index+"; next search " + 299 "begins at "+pattern_carry_g.lastIndex); 300 } 301 //輸出:Matched 'Java' at position 0; next search begins at 4 302 //解析:正則表達式將字符串從頭開始匹配,匹配成功 303 304 305 //test()參數是一個字符串,返回true/false,其lastIndex屬性與exec()類似 306 console.log((/hello/g).test("hello world!"));// true 307 console.log((/hello/g).test("world! world!"));// false
使用例子,待更......