正则表达式精讲

来源:互联网 发布:大数据利用过程是 编辑:程序博客网 时间:2024/05/15 20:26

正则表达式讲解:


首先要知道正则表达式到底是干什么用的?


•测试字符串是否匹配格式:例如测试手机号邮箱是否符合规则 

•替换文本内容:可以在一串文本中查找需要的内容进行批量替换

•根据匹配规则从文本中查找需要的内容:例如可以根据输入选择下拉框显示内容;


总之正则表达式在web2.0时代显得是那么强势流行,下面我们说说正则表达式如何构建


首先要了解RegExp对象,这是一个跟array一样的普通对象;

用法:创建正则表达式只需要new RegExp()即可(现在对象里面是空的 就是说创建了一个空的正则表达式 没有任何功能);

var you=new RegExp("n",'i');

该构造函数内第一个参数是正则表达式要匹配的文本内容,第二个参数是表示不分大小,其中第二个参数可以接受三个值:

g(全文查找),i(不分大小写),m(多行查找)或者组合使用,最多的使用是gi即全文查找并且不区分大小写;

一般情况下我们书写正则表达式都不会去new 一个RegExp对象 就像新建一个数组不会去new一个array一样,而是用一种对象字面量形式来代替var you=/n/g;


正则表达式有哪些属性或者方法?


方法:

test,  返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。如果存在则返回 true,否则就返回 false。

举例如下:you.test("nihao")//true

•exec, 该方法是专门为捕获组而设计的,接受一个参数,即要应用模式的字符串。然后返回包含第一个匹配项信息的数组,

           或者在没有匹配项情况下返回null,返回数组虽然是array的实例,但是包含两个特殊属性(index和input)

           其中,index表示匹配项在字符串中的位置,而input表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果存在)

           举例如下:

    var text="abcdefade";

   var a=/b(c(def)?)?/g;

   var matchs=a.exec(text);

   这个时候matchs为["bcdef",'cdef','def'];

   此时matchs.index为1(第一个匹配的b为字符串第二个位置)

   补充:关于捕获 下面会讲到,如果不懂 可以看完捕获后再回来看看该方法。

属性:

•source,返回正则表达式模式的文本的复本。只读。

•lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的开始位置。

•$1...$9,返回九个在模式匹配期间找到的、最近保存的部分。只读。

•input ($_),返回执行规范表述查找的字符串。只读。

•lastMatch ($&),返回任何正则表达式搜索过程中的最后匹配的字符。只读。

•lastParen ($+),如果有的话,返回任何正则表达式查找过程中最后括的子匹配。只读。

•leftContext ($`),返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符。只读。

•rightContext ($'),返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符。只读。

String对象一些和正则表达式相关的方法

•match,找到一个或多个正则表达式的匹配。

    举例:var str="1 and 2 and 3"

    alert(str.match(/\d+/g))//123

•replace,替换与正则表达式匹配的子串。

     举例:

     var str="1 and 2 and 3"

     alert(str.replace(/\d+/g,'n')//n and n and n

•search,检索与正则表达式相匹配的index值。

    举例:

    var str="1 and 2 and 3"

    alert(str.search(/\d+/g)//0

•split,把字符串分割为字符串数组。

举例:

var str="1 and 2 and 3"

alert(str.split(/\d+/g)//[""," and "," and ",""](当匹配第一个或者最后一个字符时候会返回两个空字符串);

以上这些都是正则表达式用法,到现在为止 其实我们还没有真正去了解正则表达式这门“语言”;

下面我们来真正走进这门语言:

--------------------------------------------------------------------------------------------------------------------------------------------

正则表达式语法详解

如果你要在一个字符串中搜索有没有at这个词,你就可以用/at/g

但是有时候我们需要查找单独的at而不是存在于cat类似中的at,那么我们就需要用到元字符去查找了\bat/g;例如"cat at car".match(/\bat/g)就会返回["at"]而不包含cat

不幸的是,很多单词里包含hi这两个连续的字符,比如him,history,high等等。用hi来查找的话,这里边的hi也会被找出来。如果要精确地查找hi这个单词的话,我们应该使用\bhi\b。

刚才我们说到了元字符,元字符是在正则表达式中有着举足轻重的分量的。

表1.常用的元字符

代码说明 .匹配除换行符以外的任意字符\w匹配字母或数字或下划线或汉字\s匹配任意空白符\d匹配数字\b匹配单词开始或结束^匹配字符串开始$匹配字符串结束

一个一个的来讲解吧

“.”这个元字符匹配处换行外的任意字符,同样举例说明"cat at car".match(/\bat\b.car/g)就会返回["at car"];

\w匹配的东西一般都是我们表单中输入框允许输入的东西例如"cat at %$%car ".match(/\w/g)就会返回["c", "a", "t", "a", "t", "c", "a", "r"];

\s匹配任意空白符,一般情况下我们都要处理用户输入的空白符"cat at %$%car ".replace(/\s/g,'')就会返回"catat%$%car";

\d匹配数字,我们上面也举过这个例子"1 and 2 and 3".match(/\d/g)这样的话就返回["1", "2", "3"];

^匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个表单需要验证你的qq号必须是数字/^\d+$/g.test("123")这里+意思是匹配一次或更多次

通常情况下这些元字符都不够用,下表就列出来一些常用限定符

表2. 常用的限定符

代码/语法说明*重复零次或更多次+重复一次或更多次?重复零次或一次{n}重复n次{n,}重复n次或更多次{n,m}重复n到m次  

*与上面例子中的+基本是一样的用法只是能不能重复零次问题 举例:/^a\w*d$/g.test("ad")会返回true而/^a\w+d$/g.test("ad")则返回false因为字母a后面的字母数字下划线等匹配数为零。

?是我们在实际应用中用的最多的一个限定符,它限定匹配的字符出现一次或者不出现都会匹配成功例如我们匹配一个电话号码约定是可以四位数字+"-"+七位数字,那么就应该这么写:

/^\d{4}[-]?\d{5}$/g.test("012323222")与/^\d{4}[-]?、d{5}$/g.test("0123-23222")都会返回true

{}的用法刚才也说到了,举个栗子吧:我们要匹配5到十二位qq号/^\d{5,12}$/g.test('12345')返回true其他任何包含非数字或者不在5到12位数之内的都会返回false;

   讲了这么多元字符和限定符,你可能会有疑问了,如果我的字符中出现*之类的怎么办。这时候你就需要用正则表达式的转义了,其实很简单例如你要匹配*只需要/\d+\*/g即可,例如:/\d+\*/g.test("123*")就可以返回true了

[]用法:字符数组,如果我们想在一个字符串中寻找特定的未定义过的几个字符怎么办呢。例如我想要在字符中找出love几个单词的匹配,那么很简单你只需要用[love]把你需要的列进去就可以了,

这个意思就是匹配任何一个love包含的字母;[]还可以指定一个范围[0-9a-zA-Z]匹配一个数字或者字母;说明:所有元字符在字符数组内部都是普通字符-不在开头除外。

()用法:()在使用时候没有特定含义,只是作为辅助用在分组指定子表达式用:如果我们想查找一组特定含义的内容重复3次,例如ip,那么就可以用到()了/^(\d{1,3}\.){3}\d{1,3}$/g;

当然这个ip匹配肯定是有问题的,我给大家一个正确的匹配 大家可以根据前面讲的综合分析一下/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/g

很多时候我们需要查找不属于某个匹配的字符,比如想查找一个html标签的内容而不包含标签本身,那么这时候我们就要用到反义了。

      表3.常用的反义代码

代码/语法说明\W匹配任意不是字母数字下换线汉字的字符\S匹配任意不是空白符的字符\D匹配任意非数字的字符\B匹配不是单词开头或结束位置[^x]匹配除了x以外的任意字符[^abcde]匹配除了abcde这几个字母以外的任意字符

例如我们想搜索var tt="gaga<a src='ni'>nihao</a>gaga"中的a标签那么就可以用tt.match(/<a.*>+[^<]+<\/a>/g);

捕获

我们单独把捕获拿出来作为一部分进行详细讲解,开始时候我们讲到了捕获,所谓捕获就是用小括号指定一个子表达式后,该表达式可以在表达式或者其他程序中做进一步处理,

上面说到用于exec方法,其实捕获不仅仅能用于exec方法中,在重复匹配某个单词或者字母时候捕获也能发挥它的作用,

默认情况下,每个捕获组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推,可以为分组指定命名。 
例如: 
(?<y>\d{4})-(?<md>\d{2}-(?<d>\d{2})) 
这个表达式由三对小括号组成分为四个组号,特别说明的是组号0代表整个表达是整体下表列出匹配结果及分组命名情况如下:

例如匹配日期2013-10-21

捕获分组命名说明编号命名捕获组匹配内容0 (?<y>\d{4})-(?<md>\d{2}-(?<d>\d{2})) 2013-10-211y(?<y>\d{4})20132md(?<md>\d{2}-(?<d>\d{2})) 10-213d(?<d>\d{2})21对捕获组引用在正则表达式一般有以下三种情况

  • 反响引用,即对前面捕获到内容进行引用
  • 作为条件判断结构
  • 在程序中对捕获组内容的引用
由于javascript中不支持命名捕获组,只是支持普通编号捕获组$number,使用方法如下:
var data = "<table id=\"test\"><tr class=\"light\"><td> text</td></tr></table>"; 
var reg = /<([a-z]+)[^>]*>/ig;
var a = data.replace(reg, "<$1>");
这样输出的就是"<table><tr><td> text </td></tr></table>";

到这里为止你是不是觉得你会用正则表达式做任何匹配校验替换了?

那么你试试匹配一个规则:输入的内容可以是纯中文可以是纯字母也可以是字母中文组合。

怎么样,知识不够用了吧。这种可以也可以的情况下就要用到正则表达式的分支条件了,分支条件就是用|把不同的规则分开去匹配例如/n|b/g匹配n或者b;

ok至此为止正则表达式的基础就这些了 我们来做个练习然后分析一下:

就拿最常用的检测邮箱规则吧:

邮箱规则是字母数字下划线.|_后三者不能作为结尾且不能连续重复出现加上@然后是字母数字下划线.|_加上.然后是com或者cn

 /^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.(com|cn)$/g;

分析如下首先()内部分可以重复多次,小括号内是以字母数字下划线开始然后是_|.可以其中一个出现一次或者不出现。然后是字母数字下划线作为@的前缀,之后一个@字符,然后是同样跟@前规则一样的表达式,

之后是一个.最后以com或者cn结尾;

练习2:去除字符串中重复字符:

var a="abbcccdddeeeffghh";

var b=a.replace(/(.)\1+/g,"$1");

结果b:"abcdefgh"

分析:此处正则表达式中()内部分就是捕获内容,\1则是捕获第一组,$1表示第一个捕获的内容

练习3:将首字母转化为大写

var reg=/\b(\w)|\s(\w)/g;

var str='hello kitty';

str.replace(reg,function(d){return d.toUpperCase()})

结果为:‘Hello Kitty’

原创粉丝点击