定義:它就是一個規則,用來處理字符串的一個規則html
用來處理字符串的一個規則 (正則只能處理字符串)正則表達式
regexp.test(string)
,匹配。regexp.exec(string)
, 捕獲。正則的處理統稱爲兩個方面:正則的匹配,正則的捕獲
功能:檢索、替換、校驗數組
JS可視化工具瀏覽器
建立正則對象
字面量方式:函數
var reg = /\d/;
實例建立方式:工具
var reg = new RegExp('\d'); // 參數是正則字符串
兩種建立方式的區別:url
//
之間包起來的全部內容都是元字符var reg = new RegExp('^\\d+' + name + '\\d+$', 'g');
每一個表達式都是由元字符和修飾符組成的spa
元字符:在//
之間具備意義的一些字符code
特殊意義的元字符
\
轉義字符^
以某一個元字符開始$
以某一個元字符結尾\n
匹配一個換行符.
除了\n
之外的任意字符()
分組, 一個大的正則劃分爲具體的小正則.x|y|z
x,y,z其中的一個[xyz]
x,或者y,或者z,其中的一個[^xyz]
非,除了x,y,z中的任何一個字符串[a-z]
a-z中的任何一個字符[^a-z]
除了a-z任意一個字符\d
包含0-9之間的數字\D
除了0-9之間的數字之外的任何字符\b
匹配一個邊界符\w
是[0-9a-zA-Z_]
,數字,字母,下劃線的任意一個字符\s
匹配一個空白字符: 空格, 製表符,換頁符 ...regexp
var reg = /\d/; // 包含0-9之間的數字 var reg2 = /^\d$/; // 只能是一個0-9之間的數字
表明出現次數的量詞元字符
*
零到屢次(不出現,1次,100次)+
一到屢次(至少須要一次)?
零次或者一次(可能出現;可能不出現,可是出現只出現一次){n}
n次{n, }
n到屢次{n, m}
n到m次
注意點:
[]
中出現的全部字符都是表明自己意思的字符(沒有特殊含義)[]
中不識別兩位數x|y
默認的優先級 例如:/^18|19$/
變成 /^(18|19)$/
只能是18或19.^
,$
的效果// 有效數字正則 , 整數,負數,0,小數 // 12, 12.1, -12, +12, 0.2, // 不是有效數字狀況:09 ,00ffxx, 0011 // 1. "."能夠出現也能夠不出現,可是一旦出現,後面必須跟着一位或者多位數字 // 2. 最開始能夠有+/-,也能夠沒有 // 3. 整數部分,一位數能夠是0-9之間的一個,多位數不能以0開頭。 var reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/;
匹配年齡
// 匹配年齡 , 年齡介於18-65之間 var reg = /^(1[8-9])([2-5]\d)(6[0-5])$/; // 18-19 20-59 60-65 var reg = /^(1[8-9]|[2-5]\d|6[0-5])$/;
不能直接使用18-65之間,就劃分10之內的數字.
錯誤寫法:
var reg = /^[18-65]$/;
[]
中不識別兩位數
var reg = /^[12]$/; // 1或2中的其中一個 var reg = /^[12-68]$/; // (1, 2-6其中的一個,8,)其中的一個 // 數字,字母,下劃線,中杆 var reg = /^[\w-]$/;
驗證郵箱
簡版驗證:
// `@`分割,左邊爲:數字,字母,下劃線,.,- var reg = /^[\w.-]+@[0-9a-zA-Z]+(\.[a-zA-Z]{2,4}){1,2}$/;
正則表達式:從現實的抽象成規律,一部分,一部分解決。
身份證號碼驗證
簡版身份證驗證:
var reg = /^\d{17}(\d|X)$/; var reg = /^(\d){2}(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; // 增長分組
非空驗證
var reg = !/^\s*$/;
去首尾空格
var reg = /^ +| +$/g;
去除html註釋
var reg = /<\!--[\s\S]*?-->/g;
exec()
捕獲個格式:
是一個數組,數組中的第一項是正則捕獲的內容,第二項是捕獲在字符串的索引位置,第三項是原始字符串
var reg = /\d+/; console.log(reg.exec('sf11')); // [ '11', index: 2, input: 'sf11' ]
exec分爲兩個階段:
正則捕獲特色:
懶惰性:每一次執行
exec
只捕獲第一個匹配的內容,在不進行任何處理的狀況下,再執行屢次捕獲,捕獲的仍是第一次匹配到的內容
lastIndex
是正則每次捕獲在字符串中開始查找的位置,默認值是:0
解決正則懶惰性,在正則末尾增長修飾符"g"
i
:igoreCase(i), 忽略大小寫匹配m
: multiline(m), 多行匹配g
: global(g),全局匹配
加全局修飾符g
,每次正則捕獲結束後,會把lastIndex
的值變爲最新的值,下次捕獲,從最近的值開始查找.
// 全局修飾符 var reg = /\d+/g; var str = 'sf11aaa111'; var res = reg.exec(str); var arr = []; while(res) { arr.push(res[0]); res = reg.exec(str); }
貪婪性: 正則的每次捕獲都是按照匹配最長的結果捕獲的。
var reg = /\d+/g; var str = 'sf2017aaa2018'; var res = reg.exec(str);
例如: 2符合正則 2017也符合,默認捕獲的是2017
解決正則的貪婪性:在量詞元字符後邊添加
?
// 只須要匹配2,而不須要匹配2017 var reg = /\d+?/g; var str = 'sf2017aaa2018'; var res = reg.exec(str); console.log(res);
?
在正則中的做用
/\d?/
出現0或1次數字, 數字可能出現也可能不出現./\d+?/g
出現一個數字.match()
把全部和正則匹配的字符都獲取到.
var reg = /\d+/g; var str = 'sf2017aaa2018'; var arr = str.match(reg); console.log(arr); // ["2017", "2018"]
match()
和exec()
區別:
正則分組的做用:
分組引用
// 分組引用 var reg = /^(\w)\1(\w)\2$/; // `\2`表示和第二個分組出現同樣的東西 , `\1`表示和第一個分組出現同樣的東西. console.log(reg.test('zzff')); // true console.log(reg.test('z1f_')); // false
分組捕獲
正則在捕獲的時候,不只僅把大正則匹配的內容捕獲到,並且還能夠把小分組匹配的內容捕獲到.
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; var str = "350426199403118019"; console.log(reg.exec(str)); // arr = ["350426199403118019", "35", "0426", "1994", "03", "11", "80", "1", "9", index: 0, input: "350426199403118019"] // arr[0] -> 大正則匹配的內容 // arr[1] -> 第一個分組捕獲的內容 // arr[2] -> 第二個分組捕獲的內容 // arr[3] -> 第三個分組捕獲的內容 // ... // 這種現象就是分組捕獲
(?:)
在分組中 ?:
只匹配,不捕獲.
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/; var str = "350426199403118019"; console.log(reg.exec(str)); // arr = ["350426199403118019", "35", "0426", "1994", "03", "11", "1", index: 0, input: "350426199403118019"]
把原有的字符替換成新的字符
每當執行一次replace只能替換一個字符
replace
的一個參數是正則:
把全部正則匹配的內容捕獲到,而後捕獲的內容替換成須要替換的新內容。
第二個參數能夠是:
// 參數和return var str = 'xixi2017xixi2018'; str = str.replace(/\d+/g, function() { // console.log(arguments); // ["2017", 4, "xixi2017xixi2018", callee: function, Symbol(Symbol.iterator): function] // ["2018", 12, "xixi2017xixi2018", callee: function, Symbol(Symbol.iterator): function] return 222222; // 返回的值,把每次大正則匹配捕獲的內容都替換該值 }); console.log(str); // xixi222222xixi222222
替換字符串中的數字爲中文數字
var str = '20170606'; // -> 貳零壹柒零陸零陸 var arr = ['零', '壹', '貳', '叄', '肆', '伍', '陸', '柒', '捌', '玖']; var reg = /\d/g; str = str.replace(reg, function($1) { console.log($1); return arr[$1]; }); console.log(str);
獲取一個字符串中出現次數最多的字符
var str = 'abaaaasdffasd'; var reg = /\w+?/gi; var obj = {}; str.replace(reg, function($0) { if (obj[$0] >= 1) { obj[$0] += 1; } else { obj[$0] = 1; } }); console.log(obj); // 獲取最大的,出現字符最多的。 // 在對象中獲取出現最屢次數,把出現最多字符拿出。 // 在一個對象獲取最大值: 假設法 // 在數組中獲取最大值:1. 排序。 2. 假設法, 3. Math.max(); // 獲取最多出現的次數 var maxNum = 0; for (var i in obj) { if (obj[i] > maxNum) { maxNum = obj[i]; } } // 獲取全部符合出現maxNum次數的都獲取到 var resArr = []; for (var key in obj) { if (obj[key] == maxNum) { resArr.push(key); } } console.log(maxNum, resArr.toString());
url 處理參數
var url = 'http://www.weibo.com/u/5688069917?pids=Pl_Official_MyProfileFeed__21&profile_ftype=1&is_all=1#_0'; var reg = /([^?=&]+)=([^?=&]+)/g; var res = reg.exec(url); var obj = {}; while(res) { obj[res[1]] = res[2]; res = reg.exec(url); } console.log(obj); // Object {pids: "Pl_Official_MyProfileFeed__21", profile_ftype: "1", is_all: "1#_0"}
var url = 'http://www.weibo.com/u/5688069917?pids=Pl_Official_MyProfileFeed__21&profile_ftype=1&is_all=1#_0'; var reg = /([^?=&]+)=([^?=&]+)/g; var res = reg.exec(url); var obj = {}; url.replace(reg, function($0, $1, $2) { obj[$1] = $2; }); console.log(obj); // Object {pids: "Pl_Official_MyProfileFeed__21", profile_ftype: "1", is_all: "1#_0"}
時間字符串格式化
// "2017-6-7 23:43:12" --> "2017年06月07日 23時:43分12秒" var str = '2017-6-7 23:43:12'; // 方法一: 字符串變數組, 經過空格,拆成兩項 // ['2017-6-7', '23:43:12'] var arr1 = str.split(' '); var arrL = arr1[0].split('-'); // ["2017", "6", "7"] var arrR = arr1[1].split(':'); // ["23", "43", "12"] // 方法二: 時間格式字符串,變成時間格式對象 經過new Date(); var d = new Date(str.replace('-', '/').replace('-', '/')); // 而後經過 時間對象的操做方式 來操做 // ie 瀏覽器中,不識別 '-' , 須要替換成 '/' // 方法三: 正則方式, 模板匹配的方式 . 設定好目標格式,把數組中固定的項替換成指定的區域內. var str = '2017-6-7 23:43:12', resStr = '{0}年{1}月{2}日 {3}時:{4}分{5}秒'; // var reg1 = /\d+/g; // var arrDate = str.match(reg1); var reg1 = /^(\d{4})[-\/](\d{1,2})[-\/](\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2})$/g; var arrDate = []; str.replace(reg1, function() { // arrDate = [].slice.call(arguments); arrDate = Array.from(arguments); arrDate = arrDate.slice(1, 7); }); // console.log(arrDate); // var arrDate = ['2017', '6', '7', '23', '43', '12']; var reg = /{(\d)}/g; resStr = resStr.replace(reg, function($0, $1) { var num = arrDate[$1]; return num < 10 ? '0' + num : num; }); console.log(resStr); // 2017年06月07日 23時:43分12秒
分組前後出現的判斷:從左向右,誰先出現就是靠前分組
方法1:
var str = '9335673817'; // 9,335,673,817 var reg = /^(\d{1,3})((?:\d{3})+)$/g; var t = str.replace(reg, function() { var result1 = arguments[1]; var reslut2 = arguments[2]; return result1 + ',' + reslut2.replace(/\d{3}(?!$)/g, function() { // 負向欲查 return arguments[0] + ','; }); });
方法2:
// 倒着數 // 9,335,673,817 // 10 - 7 - 1 // 若是字符串的長度 - 索引自己位置 - 1 模 3 == 0 ,則在這個字符串的後邊加一個',' // 在數值的前方加,第一個字符串有須要再次處理。 // 在數值的後方加,就能夠。 var str = '9335673817'; // 9,335,673,817 var reg = /\d(?!$)/g; // (?!$) 不去捕獲最後一位 var str = str.replace(reg, function(r, i){ if ((str.length - i - 1) % 3 == 0) { return r + ','; } else { return r; } }); console.log(str);
方法3:
// 倒序處理 str = str.split('').reverse().join(''); str = str.replace(/(\d{3}(?!$))/g, '$1,'); str = str.split('').reverse().join('');
re
從文本頭部到尾部開始解析。文本尾部方向叫作「前」,也就是往前走,另外一方向就是後。re
匹配規則的時候,先向前看看,是否符合斷言規則。後瞻/後顧的規則相反(JS不支持後顧)/^$/
表示嚴格匹配,以什麼開頭,以什麼結尾,只能在這裏邊
問號?
總結:
// 在正則中,把 `?`的用法和`()`的用法掌握好 // 正則中的斷言 /* (?=exp) (自己不佔寬度,確定的,向前看) (?!exp) (?<=exp) (?<!exp) (?:) 只匹配,不捕獲 (+?) (*?) ({}?) 非貪婪性 []? ()? \d? 0次或1次 */ // 【量詞】 `?`在正則中比較低調,做爲量詞的概率比較少。 var str = '-3.1415'; var reg = /^(\+|-)?\d+(\.\d+)?$/; // /^$/ 表示嚴格匹配 var reg = /^[+-]?\d+(\.\d+)?$/; // 【匹配不捕獲】 (?:) 前提:問號要放在分組前面,而且後邊緊跟冒號。 var reg = /^(?:\+|-)?\d+(?:\.(\d+))?$/; // /^$/ 表示嚴格匹配 // 【非貪婪性】 把問號放在量詞後邊: +? *? {}? (+?) (*?) ({}?) // 正則的特色: 懶惰,貪婪。 var reg = /\d+/; var str = 'abc2342xyz236asdf456456'; console.log(str.match(reg)); // str.replace(reg, function() { // console.log(arguments); // }); var reg = /(\d+)/; reg.test(str); // 匹配的存儲在構造函數上RegExp.$1; 構造函數上有九個來存儲匹配到值 console.log(RegExp.$1);
欲查
特色:
欲查修飾左邊,若是前面沒有修飾空表達式,空正則.
(?!exp) Zero-width positive lookahead
(自己不佔寬度,確定的,向前看)
正則中的斷言Assert
前提, 前提條件
var str = '13456789'; var reg = /(\d)(?=(?:\d{3})+$)/g; // $ 匹配到結尾 str = str.replace(reg, function() { // console.log(arguments); return arguments[0] + ','; }).replace(reg, '$1,'); console.log(str);