基础
正则表达式的创建
JavaScript有两种方式创建一个正则表达式:
var reg=/a/g;
var reg=newRegExp("a","g");
正则中分为两个部分 一个是正则匹配内容 另一个是修饰符部分
修饰符分为 i不区分大小写 g全局从头查找到尾部 m匹配多行
正则表达式的属性和方法
// 属性
var reg=/a/g;
console.log(reg.flags) // 修饰符
console.log(reg.source) // 正则匹配的内容
// 方法
var reg=/a/g;
var str = "abcdefg"
reg.test(str); // true 判断字符串是否满足正则匹配内容
reg.exec(); // 查找字符串中满足正则匹配内容的结果 并且返回一个数组 这个数组只有一个元素
// 几个属性
// groups 群组
// index 查找到的索引下标
// input 当前查找的字符串是什么
// 没用的方法哦
正则表达式在字符串方法中的应用
str.search()
按照正则表达式查找字符串中的内容 返回优先查找到的第一个元素下标
var str="abcdefg";
console.log(str.search(/a/)); // 0 第一个
str.split();
按照正则表达式匹配内容 切割字符串 并且返回一个数组
var str="abcdefg";
console.log(str.split(/[cf]/g)) // 用c或f进行切割
str.replace()
按照正则表达式匹配内容 进行替换 可以替换成相同的 也可以替换成不同的
// 使用方法
str.replace(正则表达式,回调函数(item,index){
// return返回要替换的内容
})
// 第一题
var str = "abcdeabcde"
str=str.replace(/a/g,function(item,index){
return index===0?"x":"y";
})
console.log(str) // xbcdeybcde 第一个a换成x 剩下的a换成y
// 第二题
var str = "abcdeabcde"
var arr=[];
str.replace(/a/g,function(item,index){
arr.push(index)
})
console.log(arr) // 0,5 查找所有匹配正则元素的下标
// 第三题
var str = "abcdefghigkl"
str=str.replace(/[bdf]/g,"0")
console.log(str) // a0c0e0ghigkl 将满足正则的替换成0
// 第四题
var str="abcabcabf";
str = str.replace(/[abc]/g,function(item){
switch(item){
case "a" : return "1"
case "b" : return "2"
case "c" : return "3"
}
})
console.log(str) // 12312312f a替换为1 b替换为2 c替换为3
str.match()
在这里 可以传入一个正则表达式
如果该正则表达式:
1.不是全局g查找 那么这个方法与exec()相同
2.不是全局查找 但是加群组 则先返回找到的元素外 再返回群组元素
3.是全局查找 将会返回满足正则的所有元素的数组
元字符
.
. 可以代表任意 单个 字符
console.log("cetcotcat".match(/c.t/g)) // 匹配c什么t
console.log("cetc.tcat".match(/c\.t/g)) // 匹配c.t 需要使用转义字符\
console.log("caaatcbbbbt".match(/c...t/g)) // 匹配caaat
[ ]
可以满足方括号内的任意一个字符
console.log("cetcotcat".match(/c[ae]t/g)) // cat cet
// [1-31] 相当于 [1-3 1] 匹配1 2 3
// [a-Z] 报错
// [A-z] 其中字母以外的其他字符 不能用
// [a-zA-Z] 大小写字母
// a[b.c]b 方括号[]中的. 是字符. abb a.b acb
// a[\[\]]]b 方括号[]中的[] 需要转义
// [aaaaa] 方括号[]中的重复是无意义的
中括号中的 ^
在 [ ] 中 第一位 使用^ 表示除了^后面的字符外都满足
console.log("abcafcadcaec".match(/a[^f]/c/g)) // abc adc aec 不要中间是f的
console.log("abcafcadcaec".match(/a[a^f]/c/g)) // 如果不在第一位 就表示字符^
转义特殊字符
\w [a-zA-Z0-9]
\W [^a-zA-Z0-9]
\d [^a-zA-Z0-9]
\D [^a-zA-Z0-9]
\s 空格
\S 非空格
// 剔除空格
var str=" ac bg de ";
str=str.replace(/\s/g,"");
console.log(str) // acbgde 将所有的空格替换为空字符串""
{ }
一般情况下
{}内的数字 代表需要匹配几次
var str="1978-12-19"
var reg = /\d{4}-\d{2}-\d{2}/
console.log(reg.test(str)) // true {}内写一个数 代表固定重复几次
reg1 = /abc{2}/ // 这里是abcc
reg2 = /(abc){2}/ // 这里是abcabc
reg3 = /a{0}/ // 没有a 意味着匹配一个空字符
{1,} 需要满足一次及一次以上
{0,} 需要0次或者0次以上
{3,8} 需要满足3至8次
? + *
? 代表匹配前面的表达式满足0次或1次 {0,1}
+ 代表匹配前面的子表达式一次或多次 {1,}
- 代表匹配前面的子表达式零次或多次 {0,}
// 我想要 str 里的 item和items
var str = "item and items and itemes"
var arr=str.match(/items?\s/g).map(function(item){
// "item "或者"items " ?代表有没有s都行 这时三个都可以通过 但是后面还需要有\s空格才可以匹配 所以只有前两个 但是末尾有空格
return item.replace(/\s/g,""); // 将空格替换为空字符串
})
console.log(arr);
贪婪匹配 非贪婪匹配
在默认的情况下为贪婪匹配 重复会从大向小查找
var str = "aaaaaabbb"
console.log(str.match(/a{2,4}/g)) // "aaaa" "aa" 并不是"aa" "aa" "aa"
console.log("aaaaaa".match(/a.{3,4}/g)) // aaaa
console.log("aaaaaabbb".match(/a{0,4}/g)) // aaaa aa "" "" "" ""
console.log("bbbabbbaaabbbbaabbb".match(/a{1,}/g)) // a aaa a
console.log("bbbabbbaaabbbbaabbb".match(/a{0,}/g)) // 算上空字符 17个
加个问号 就是非贪婪匹配了
var str = "aaaaaabbb"
console.log(str.match(/a{2,4}?/g)) // "aa" "aa" "aa"
.+? .*?
// 我想要a开始b结束 中间有零个或多个字符的字符串
// .是任意字符 *是0次或多次
var str = abaab;
console.log(str.match(a.*b)) // abaab 贪婪模式中 尽可能大的截取 不符合预期
console.log(str.match(a.*?b)) // ab aab 非贪婪模式 越短越好 满足就截取
// 同理 .+? 有一个或多个字符
var str = ababaab
console.log(str.match(a.+?b)) // abab aab ab中间必须有1或多个字符 不能截出ab这种
// 将下列所有标签都换成p标签
var str = "<div>def<span>ghi</span></div><div><a href='#'>abc</div>"
var str = str.replace(/<\/?.+?>/g,function(item){ //< 开始 /可有可无 .+? 一个以上的字符 >结束
console.log(item)
if(item.match(/\//)) return "</p>"
else return "<p>"
})
console.log(str)
|
或者 指明两项之间的一个选择
如果是a或者b 可以直接用[ab] 但如果是ab或者bc 只能使用ab|bc
// 如果|得一端没有内容,则认为匹配空字符
console.log("abcdef".match(/|a|b/g)) // "" "" "" "" "" "" ""
console.log("abcdef".match(/a||b/g)) // a "" "" "" "" "" ""
console.log("abcdef".match(/a|b|/g)) // a b "" "" "" "" ""
^$
起始和结束
// 判断输入的数字是1-31之内的
<body>
<input type="text"><span></span>
<script>
var input, span;
init();
function init() {
input = document.querySelector("input");
span = document.querySelector("span");
input.addEventListener("input", inputHandler);
}
function inputHandler(e) {
if (this.ids) return; // 如果定时器存在 跳出
this.ids = setTimeout(function (input) {
clearTimeout(input.ids); // 清除定时器
input.ids = false;
testInputValue(input.value);
}, 500, this); // 0.5秒进入一次testInputValue
}
function testInputValue(txt) {
console.log(txt.match(/^[1-9]$|^[12][0-9]$|^3[01]$/))
// 从开始到结束1-9 或者10-29 或者30-31
if (/^[1-9]$|^[12][0-9]$|^3[01]$/.test(txt)) { // 通过了
span.textContent = "输入正确";
span.style.color = "green";
} else { // 没通过
span.textContent = "输入错误";
span.style.color = "red";
}
}
</script>
</body>
( )
群组
var str="13811111111".match(/(\d{3})(\d{4})(\d{4})/).slice(1).reduce(function(value,item,index){ // match在没有全局g且有群组的情况下 会先返回符合的元素 再返回群组
return index===1 ? value+"****" : value+item;
},"")
console.log(str);
// $1就是第一个群组,$2就是第二个群组,$3就是第三个群组
var str="13822222222".replace(/(\d{3})(\d{4})(\d{4})/,"$1****$3");
console.log(str);
断言
// 零宽正向先行断言 (?=a)
// 找出后面紧跟"d"的位置 替换为"D"
console.log("abcdabcd".replace(/(?=d)/g,"D")); // abcDdabcDd
// 找出后面紧跟"b"的"a"的位置 替换为"A"
console.log("abaccb".replace(/a(?=b)/g,"A")); // Abaccb
// 零宽负向先行断言 (?!a)
// 找出后面没有紧跟"d"的位置 都替换为"D"
console.log("abcdabcd".replace(/(?!d)/g,"D")); // DaDbDcdDaDbDcdD c后面是d 不加
// 找出后面没有紧跟"b"的"a"的位置 替换为"A"
console.log("abaccb".replace(/a(?!b)/g,"A")); // abAccb
// 零宽正向后行断言 (?<=a)
// 找出前面是"d"的位置 替换为"D"
console.log("abcdabcd".replace(/(?<=d)/g,"D")); // abcdDabcdD
// 找出前面是"b"的"a"的位置 替换为"A"
console.log("abaccb".replace(/(?<=b)a/g,"A")); // abAccb
// 零宽负向后行断言 (?<=a)
// 找出前面不是"d"的位置 替换为"D"
console.log("abcdabcd".replace(/(?<!d)/g,"D")); // DaDbDcDdaDbDcDd a前面是d 不加
// 找出前面不是"b"的"a"的位置 替换为"A"
console.log("abaccb".replace(/(?<!b)a/g,"A")); // Abaccb
案例
实现添加类名addClass和删除类名removeClass 且添加相同类名不会重复
<body>
<div class=" div1 div3 div2 "></div>
<script>
function addClass(elem,className){
// 将原来的class与需要添加的class连起来 取不是空格的地方
// match加全局 没有群组 返回满足正则的所有元素的数组
// 也就是去除空格后的所有类名
var arr=(elem.className+" "+className).match(/\S+/g);
arr=arr.filter(function(item,index,arr){
// 去重 item在数组中的下一个位置开始 还有没有重复的
// 如果没有重复的 就放入数组
return arr.indexOf(item,index+1)<0;
});
elem.className=arr.join(" "); // 给elem添上classname
}
function removeClass(elem,className){
var arr=elem.className.match(/\S+/g); // 把原来的className取出
var arr1=className.match(/\S+/g); // 把删除的className取出
arr1.forEach(function(item){ // 遍历需要删除的ClassName item是要删的
arr=arr.filter(function(t){
return t!==item; // 返回arr中不等于item的类名
});
});
elem.className=arr.join(" ");// 给elem添上classname
}
</script>
</body>
2[2[abc]3[bc]]
var str = "3[2[2[abc]3[d]]4[e]]";
function decodeString(str) {
var reg1 = /\d+\[[a-zA-Z]+\]/g;
// 数字 [ 字母 ] 有全局没有群组 返回所有符合规则的元素
// 只能匹配到中间没有字符的 所以从最内层的开始
var reg2 = /(\d+)\[([a-zA-Z]+)\]/
// (数字) [ (字母) ] 有群组没有全局 返回符合的元素和群组元素
if (!reg1.test(str)) return str; // 出口
str = str.replace(reg1, function (item, index) {
console.log(item) // 最内层拆分的每一个组合
var arr = item.match(reg2).slice(1);
// 通过match群组拿出数字和字符 第一项是符合的元素(自己) 所以截掉
// arr中第一项是数字 第二项是字母
var s = arr[1].repeat(arr[0]);
return s; // s替换最内层的每个组合
});
str=decodeString(str) // 递归
return str;
}
console.log(decodeString(str));
来源:CSDN
作者:Yee:)
链接:https://blog.csdn.net/weixin_44383477/article/details/103929847