摘要:把字符串中符合正則的規(guī)則捕獲到,捕獲。在對象中獲取出現(xiàn)最多次數(shù),把出現(xiàn)最多字符拿出。在一個對象獲取最大值假設法在數(shù)組中獲取最大值排序。表示嚴格匹配非貪婪性把問號放在量詞后邊正則的特點懶惰,貪婪。
正則基礎
定義:它就是一個規(guī)則,用來處理字符串的一個規(guī)則
用來處理字符串的一個規(guī)則 (正則只能處理字符串)
判斷一個字符串是否符合制定的規(guī)則 regexp.test(string) ,匹配。
把字符串中符合正則的規(guī)則捕獲到 regexp.exec(string), 捕獲。
正則的處理統(tǒng)稱為兩個方面:正則的匹配,正則的捕獲
功能:檢索、替換、校驗
JS可視化工具
創(chuàng)建正則對象
字面量方式:
var reg = /d/;
實例創(chuàng)建方式:
var reg = new RegExp("d"); // 參數(shù)是正則字符串
兩種創(chuàng)建方式的區(qū)別:
字面量方式不能拼接字符串,//之間包起來的所有內(nèi)容都是元字符
實例創(chuàng)建方式不認識元字符,需要通過轉(zhuǎn)義.
var reg = new RegExp("^d+" + name + "d+$", "g");元字符
每個表達式都是由元字符和修飾符組成的
元字符:在//之間具有意義的一些字符
特殊意義的元字符
轉(zhuǎ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之間的數(shù)字
D 除了0-9之間的數(shù)字以外的任何字符
匹配一個邊界符
w 是[0-9a-zA-Z_],數(shù)字,字母,下劃線的任意一個字符
s 匹配一個空白字符: 空格, 制表符,換頁符 ...
var reg = /d/; // 包含0-9之間的數(shù)字 var reg2 = /^d$/; // 只能是一個0-9之間的數(shù)字
代表出現(xiàn)次數(shù)的量詞元字符
* 零到多次(不出現(xiàn),1次,100次)
+ 一到多次(至少需要一次)
? 零次或者一次(可能出現(xiàn);可能不出現(xiàn),但是出現(xiàn)只出現(xiàn)一次)
{n} n次
{n, }n到多次
{n, m} n到m次
注意點:
在[]中出現(xiàn)的所有字符都是代表本身意思的字符(沒有特殊含義)
[]中不識別兩位數(shù)
分組的作用改變x|y默認的優(yōu)先級 例如:/^18|19$/ 變成 /^(18|19)$/ 只能是18或19.
分組可以一直有^,$的效果
// 有效數(shù)字正則 , 整數(shù),負數(shù),0,小數(shù) // 12, 12.1, -12, +12, 0.2, // 不是有效數(shù)字情況:09 ,00ffxx, 0011 // 1. "."可以出現(xiàn)也可以不出現(xiàn),但是一旦出現(xiàn),后面必須跟著一位或者多位數(shù)字 // 2. 最開始可以有+/-,也可以沒有 // 3. 整數(shù)部分,一位數(shù)可以是0-9之間的一個,多位數(shù)不能以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以內(nèi)的數(shù)字.
錯誤寫法:
var reg = /^[18-65]$/;
[]中不識別兩位數(shù)
var reg = /^[12]$/; // 1或2中的其中一個 var reg = /^[12-68]$/; // (1, 2-6其中的一個,8,)其中的一個 // 數(shù)字,字母,下劃線,中桿 var reg = /^[w-]$/;
驗證郵箱
簡版驗證:
// `@`分割,左邊為:數(shù)字,字母,下劃線,.,- var reg = /^[w.-]+@[0-9a-zA-Z]+(.[a-zA-Z]{2,4}){1,2}$/;
正則表達式:從現(xiàn)實的抽象成規(guī)律,一部分,一部分解決。
身份證號碼驗證
簡版身份證驗證:
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 = //g;捕獲
exec()
捕獲個格式:
是一個數(shù)組,數(shù)組中的第一項是正則捕獲的內(nèi)容,第二項是捕獲在字符串的索引位置,第三項是原始字符串
var reg = /d+/; console.log(reg.exec("sf11")); // [ "11", index: 2, input: "sf11" ]
exec分為兩個階段:
每一次捕獲的時候都是先進性默認的匹配,如果沒有匹配成功的,捕獲的結果是null
如果匹配成功,默認匹配第一匹配的內(nèi)容
正則捕獲特點:
懶惰性:每一次執(zhí)行exec只捕獲第一個匹配的內(nèi)容,在不進行任何處理的情況下,再執(zhí)行多次捕獲,捕獲的還是第一次匹配到的內(nèi)容
lastIndex 是正則每次捕獲在字符串中開始查找的位置,默認值是:0
解決正則懶惰性,在正則末尾增加修飾符"g"
i :igoreCase(i), 忽略大小寫匹配
m : multiline(m), 多行匹配
g : global(g),全局匹配
加全局修飾符g,每次正則捕獲結束后,會把lastIndex的值變?yōu)樽钚碌闹?,下次捕獲,從最近的值開始查找.
// 全局修飾符 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);
?在正則中的作用
放在一個普通元字符后面表示出現(xiàn)0-1次。 例如:/d?/ 出現(xiàn)0或1次數(shù)字, 數(shù)字可能出現(xiàn)也可能不出現(xiàn).
放在一個量詞元字符后邊,是取消捕獲時候的貪婪性。 例如:/d+?/g 出現(xiàn)一個數(shù)字.
match()
把所有和正則匹配的字符都獲取到.
var reg = /d+/g; var str = "sf2017aaa2018"; var arr = str.match(reg); console.log(arr); // ["2017", "2018"]
match()和exec()區(qū)別:
match獲取一次,exec需要多次獲取
match中存在一些問題,在分組捕獲的情況下,match只能捕獲到大正則匹配的內(nèi)容,而無法捕獲到小正則捕獲的內(nèi)容.
分組捕獲正則分組的作用:
改變優(yōu)先級
分組引用
分組捕獲
分組引用
// 分組引用 var reg = /^(w)1(w)2$/; // `2`表示和第二個分組出現(xiàn)一樣的東西 , `1`表示和第一個分組出現(xiàn)一樣的東西. console.log(reg.test("zzff")); // true console.log(reg.test("z1f_")); // false
分組捕獲
正則在捕獲的時候,不僅僅把大正則匹配的內(nèi)容捕獲到,而且還可以把小分組匹配的內(nèi)容捕獲到.
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] -> 大正則匹配的內(nèi)容 // arr[1] -> 第一個分組捕獲的內(nèi)容 // arr[2] -> 第二個分組捕獲的內(nèi)容 // arr[3] -> 第三個分組捕獲的內(nèi)容 // ... // 這種現(xiàn)象就是分組捕獲
(?:) 在分組中 ?:只匹配,不捕獲.
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
把原有的字符替換成新的字符
每當執(zhí)行一次replace只能替換一個字符
replace的一個參數(shù)是正則:
把所有正則匹配的內(nèi)容捕獲到,然后捕獲的內(nèi)容替換成需要替換的新內(nèi)容。
第二個參數(shù)可以是:
固定的字符串值
回調(diào)函數(shù) (正則在字符串中捕獲多少次,回調(diào)函數(shù)就執(zhí)行幾次);每一次執(zhí)行匿名函數(shù),里面?zhèn)鬟f的參數(shù)值arguments和exec捕獲到的結果是非常的類似的(即使正則有分組,同樣可以通過arguments獲取到分組捕獲的內(nèi)容);return 返回的是什么,就相當于把當前的這一次大正則捕獲的內(nèi)容替換成返回的內(nèi)容。
// 參數(shù)和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; // 返回的值,把每次大正則匹配捕獲的內(nèi)容都替換該值 }); console.log(str); // xixi222222xixi222222
替換字符串中的數(shù)字為中文數(shù)字
var str = "20170606"; // -> 貳零壹柒零陸零陸 var arr = ["零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"]; var reg = /d/g; str = str.replace(reg, function($1) { console.log($1); return arr[$1]; }); console.log(str);
獲取一個字符串中出現(xiàn)次數(shù)最多的字符
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); // 獲取最大的,出現(xiàn)字符最多的。 // 在對象中獲取出現(xiàn)最多次數(shù),把出現(xiàn)最多字符拿出。 // 在一個對象獲取最大值: 假設法 // 在數(shù)組中獲取最大值:1. 排序。 2. 假設法, 3. Math.max(); // 獲取最多出現(xiàn)的次數(shù) var maxNum = 0; for (var i in obj) { if (obj[i] > maxNum) { maxNum = obj[i]; } } // 獲取所有符合出現(xiàn)maxNum次數(shù)的都獲取到 var resArr = []; for (var key in obj) { if (obj[key] == maxNum) { resArr.push(key); } } console.log(maxNum, resArr.toString());
url 處理參數(shù)
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"; // 方法一: 字符串變數(shù)組, 通過空格,拆成兩項 // ["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 瀏覽器中,不識別 "-" , 需要替換成 "/" // 方法三: 正則方式, 模板匹配的方式 . 設定好目標格式,把數(shù)組中固定的項替換成指定的區(qū)域內(nèi). 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秒千分符
分組先后出現(xiàn)的判斷:從左向右,誰先出現(xiàn)就是靠前分組
方法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:
// 倒著數(shù) // 9,335,673,817 // 10 - 7 - 1 // 如果字符串的長度 - 索引本身位置 - 1 模 3 == 0 ,則在這個字符串的后邊加一個"," // 在數(shù)值的前方加,第一個字符串有需要再次處理。 // 在數(shù)值的后方加,就可以。 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匹配規(guī)則的時候,先向前看看,是否符合斷言規(guī)則。后瞻/后顧的規(guī)則相反(JS不支持后顧)
/^$/ 表示嚴格匹配,以什么開頭,以什么結尾,只能在這里邊
問號?總結:
// 在正則中,把 `?`的用法和`()`的用法掌握好 // 正則中的斷言 /* (?=exp) (本身不占寬度,肯定的,向前看) (?!exp) (?<=exp) (?欲查
特點:
不消耗字符
修飾左邊元字符
檢測任意元字符,任意位數(shù)
欲查修飾左邊,如果前面沒有修飾空表達式,空正則.
(?!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);
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88299.html
閱讀 2648·2021-11-12 10:36
閱讀 2291·2021-08-23 09:47
閱讀 1734·2019-08-30 15:44
閱讀 1431·2019-08-30 14:10
閱讀 2265·2019-08-29 16:52
閱讀 2364·2019-08-29 16:40
閱讀 1611·2019-08-29 16:17
閱讀 2438·2019-08-26 13:21