精通正则表达式

时间:2022-10-06 16:38:43

什么是正则表达式

正则表达式是一种特殊的字符串模式,用于匹配一组字符串。

1. 原字符介绍

"^": ^会匹配行或者字符串的起始位置,有时候还会匹配整个文档的起始位置。

"$": 匹配行或者字符串的结尾

"\b": 不会消耗任何字符只匹配一个位置,常用于匹配单词边界 如我想匹配字符串中“This is Regex” 匹配单独的单词“is”正则就要写成“\bis\b”

"\d": 匹配数字

"\w": 匹配字母,数字,下划线

"\s": 匹配空格

         例如:例如字符 "a b c5" 正则:"\w\s\w\s\w"  一个字符后跟一个空格,如有字符间有多个空格直接把"\s" 写成 "\s+" 让空格重复

".":  匹配除了换行符以外的任何字符

       这个是"\w"的plus版了,"\w"不能匹配 空格,如果把字符串加上空格就无法用"\w"了,例如匹配字符串aa bb cc 32_tty ,正则:
var rex=/\w+/;str.match(rex)结果是aa,无法匹配整个完整的字符串。
"[abc]": 查找集合内的任意字符

        只是简单匹配括号内存在的字符,还可以写成[a-z]匹配a至z的所有字母

        需要注意的是,看见过有些人在[]的字符中加|或者,字符等其它字符来分隔,这样的做法是错误的。

        例如匹配手机号码的正则这么写:/^0?1[3|4|5|7|8]\d{9}$/

        如果写一段字符串“1|381016160” 也能匹配成功。应该使用的是下面的:

"(a|b|c)": 查找任何指定的选项。

"[^abc]": 查找集合外的任意字符

2. 反义

改为大写,意思就和原来的相反了。

"\W"    匹配任意不是字母,数字,下划线的字符

"\S"    匹配任意不是空白符的字符

"\D"   匹配任意非数字的字符

"\B"    匹配不是单词开头或结束的位置

3. 量词

先解释关于量词所涉及到的重要的三个概念

    贪婪(贪心) 如"*"字符 贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果 失败则回退一个字符,然后再次尝试回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的,

   懒惰(勉强) 如 "?"  懒惰量词使用另一种方式匹配,它从目标的起始位置开始尝试匹配,每次检查一个字符,并寻找它要匹配的内容,如此循环直到字符结尾处。

   占有  如"+" 占有量词会覆盖事个目标字符串,然后尝试寻找匹配内容 ,但它只尝试一次,不会回溯

     "*"(贪婪)   重复零次或更多

     例如"aaaaaaaa" 匹配字符串中所有的a  正则: "a*"   会出到所有的字符"a"

     "+"(懒惰)   重复一次或更多次

       例如"aaaaaaaa" 匹配字符串中所有的a  正则: "a+"  会取到字符中所有的a字符,  "a+"与"a*"不同在于"+"至少是一次而"*" 可以是0次,

       稍后会与"?"字符结合来体现这种区别

     "?"(占有)   重复零次或一次

       例如"aaaaaaaa" 匹配字符串中的a 正则 : "a?" 只会匹配一次,也就是结果只是单个字符a

   "{n}"  重复n次

       例如从"aaaaaaaa" 匹配字符串的a 并重复3次 正则:  "a{3}"  结果就是取到3个a字符  "aaa";

   "{n,m}"  重复n到m次

       例如正则 "a{3,4}" 将a重复匹配3次或者4次 所以供匹配的字符可以是三个"aaa"也可以是四个"aaaa" 正则都可以匹配到

     "{n,}"  重复n次或更多次

       与{n,m}不同之处就在于匹配的次数将没有上限,但至少要重复n次 如 正则"a{3,}" a至少要重复3次

       "?="    匹配任何其后紧接指定字符串 n 的字符串。

            例如:var str="Hello World!Hello";

                       var rex=/llo(?= World)/g;  

                       结果是红色部分:Hello World!Hello

        "?!"    匹配任何其后没有紧接指定字符串 n 的字符串。

            例如:var str="Hello World!Hello";

                       var rex=/Hello(?! World)/g;

                       结果是红色部分:Hello World!Hello

4. 懒惰限定符

 "*?"   重复任意次,但尽可能少重复 

如 "acbacb"  正则  "a.*?b" 只会取到第一个"acb" 原本可以全部取到但加了限定符后,只会匹配尽可能少的字符 ,而"acbacb"最少字符的结果就是"acb" 

"+?"  重复1次或更多次,但尽可能少重复

     与上面一样,只是至少要重复1次

"??"  重复0次或1次,但尽可能少重复

      如 "aaacb" 正则 "a.??b" 只会取到最后的三个字符"acb"

"{n,m}?"  重复n到m次,但尽可能少重复

          如 "aaaaaaaa"  正则 "a{0,m}" 因为最少是0次所以取到结果为空

"{n,}?"    重复n次以上,但尽可能少重复

          如 "aaaaaaa"  正则 "a{1,}" 最少是1次所以取到结果为 "a"

5. 修饰符
"g"    全局匹配
"i"     忽略大小写
"m"   执行多行匹配
 
下面来做几个练习:
1. 写一个正则表达式验证邮箱格式。
2. 写一个正则表达式将字符串中的数字提取出来。
3. 写一个正则表达式将网址中的域名提取出来。
4. 用正则表达式写一个函数来获取参数。(练习plus版)
 
————————————————------答案分割线————————————————------
 
 
 
答案:
1. var rex=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
讲解:([-+.]\\w+)*      -或+或.开头,后面跟1个或者多个字母,整体出现0次或多次

           注意前面的^和后面的$

 

 

2. var str="我是测试数据用来提取数字3456或者3222哈哈";
    var rex=/\d+/ig;
    结果:["3456", "3222"]
 
3. var rex=/(\w+:\/\/www\.)?\w+\.\w+/gi;
    结果是: http://www.apple.com
4. 
function getParam (url, param) {
var r = new RegExp("\\\\?(?:.+&)?" + param + "=(.*?)(?:[\\?&].*)?$");
var m = url.match(r);
return m ? m[1] : "";
}

 

 
 
你学会了吗?