javascript正则表达式

正则表达式(简单到高级)

正则表达式,又称正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

其实每个语言的正则表达式都比较苟同。

js正则表达式

正则表达式对象

一、对象:
正则表达式书写的两种风格perl和js(都可以在js中使用),pattern表示需要匹配的规则,其中flags表示的参数:

  • g (全文查找出现的所有 pattern)
  • i (忽略大小写)
  • m (多行查找)

perl风格:

#pattern-规则
#flags-参数
var  reg = /pattern/[flags]

js风格

//pattern-规则
//flags-参数
 var  reg = new  RegExp("pattern",["flags "])

二、方法
test()
返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。
字如其名,意思是测试,返回True或者false。

//字符串
var str="abc def abc def";
//正则表达式
var reg=/a/gi;
//弹出测试的真值
alert(reg.test(str))

exec()
用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组。可以通过循环挨个取出。
1、测试

//字符串
var str="abc def abc def";
//正则表达式
var reg=/a/gi;
//循环取出匹配到的字符a
while((r=reg.exec(str))!=null){
    document.write(r+"<br/>");
}

2、一个大坑之下标指针
先看一个代码:

//字符串
var str="abc def abc def";
//正则表达式
var reg=/a/gi;
//测试有无匹配,返回True
alert(reg.test(str))
//循环取出匹配到的字符串
while((r=reg.exec(str))!=null){
    document.write(r+"<br/>");
}

正确结果有两个a被打印,但结果只有一个a,这是为什么呢?
通过exec()的属性找到了原因:
Index 属性中包含了整个被查找字符串中被匹配的子字符串的位置。

//其他均不变,只有打印输出改变
document.write(r+"的下标索引:"+r.index+"<br/>");

得到下标索引为:8
结论:reg.test(str);在匹配字符串时,reg的下标索引到了第一个a的后面,所以下次开始的时候直接找到了第二个a。

String对象

search()/ split() / match() /replace()

search方法
返回与正则表达式查找内容匹配的第一个子字符串的位置。

//字符串
var str="abc def abc def";
//正则表达式
var reg=/def/gi;
//弹出匹配到字符串的位置
alert(str.search(reg))
//结果
4

split方法
将一个字符串分割为子字符串,然后将结果作为字符串数组返回。

//字符串
var str="abc def abc def";
//弹出分割后的字符
alert(str.split(" "));
//结果
abc,def,abc,def

match方法
使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回。(所有符合正则表达式条件的都会返回,和search的区别之一)

//字符串
var str="abc def abc def";
//正则表达式
var reg=/def/gi;
//弹出结果
alert(str.match(reg));
//结果
def,def

replace方法

//字符串
var str="abc def abc def";
//正则表达式
var reg=/def/gi;
//弹出替换后的结果
alert(str.replace(reg,"hello"));
//结果
abc hello abc hello

元字符
在正则中代表了一个特殊的符号 ( 它代表了一个语义),如果要查找这种符号,则必须转义.

(   [  {   \  ^  $  |  )  ?  *  +  .   

比如需要匹配\,则需要\\

//字符串
//在字符串\'字符'表示的另外的含义,所以要加两个\\
var str="a\\bc d\\e\\f a\\bc def";
//正则表达式
var reg=/\\/gi;
//循环输出
while((r=reg.exec(str))!=null){
    document.write(r+"的下标索引:"+r.index+"<br/>");
}
//结果
\的下标索引:1
\的下标索引:6
\的下标索引:8
\的下标索引:12

正则表达式字符

字符 描述
. [^\n\r],除\n\r外的其它字符
\d 一个数字
\D 非一个数字
\w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’
\s 匹配任何空白字符,包括空格、制表符、换页符等等
\S 匹配任何非空白字符
\u4e00-\u9fa5 中文

量词

字符 描述
0或1
* 0或多次
+ 至少一次
{n} n次
{n,} 至少n次
{n,m} 至少n次至多m次

^
1、非
[^abc]Hello
表示 Hello前不能是 a /b/c
2、行开头 行结尾
匹配输入字符串的开始位置和结束为止。
匹配的是整个字符串

//字符串
var str="abc 1def 1abc def";
//正则表达式
var reg=/^[\w\s]*$/gi;
//输出
while((r=reg.exec(str))!=null){
    document.write(r+"<br/>");
}
//结果
abc 1def 1abc def

$妙用
无$:(浏览器会假死)

 //字符串
 var str="(abc 1def 1abc def";
 //正则表达式 $妙用(有无$)
 var reg=/^[\w\s]*/gi;
 //输出
 while((r=reg.exec(str))!=null){
     document.write(r+"<br/>");
 }

在没有成功匹配到结果时,有$结束则会立刻结束

分组

分组原理(exec原理):
存分组的总的结果,和里面所包含所有元素的结果。
1、单个分组

<script>
    //字符串
    var str="j123in t345ian xing qi wu shi ma?";
    //正则表达式
    var reg=/(\d+)([a-z]+)/gi;
    //输出
    while((r=reg.exec(str))!=null){
        document.write("r:  "+r+"<br/>");
        document.write("r[0]:   "+r[0]+"<br/>");
        document.write("r[1]:   "+r[1]+"<br/>");
        document.write("r[2]:   "+r[2]+"<br/>");
        document.write("r[0][0]:    "+r[0][0]+"<br/>");
        document.write("r[1][0]:    "+r[1][0]+"<br/>");
        document.write("r[1][1]:    "+r[1][1]+"<br/>");
        document.write("r[1][2]:    "+r[1][2]+"<br/>");
    }
</script>
//结果
//第一个是总的匹配,第二个是总的匹配下面所有的元素
r: 123,123
r[0]: 123
r[1]: 123
r[2]: undefined
r[0][0]: 1
r[1][0]: 1
r[1][1]: 2
r[1][2]: 3
r: 345,345
r[0]: 345
r[1]: 345
r[2]: undefined
r[0][0]: 3
r[1][0]: 3
r[1][1]: 4
r[1][2]: 5

2、多个分组

<script>
    //其他均未改变,只改变正则表达式
    //正则表达式
    var reg=/(\d+)([a-z]+)/gi;
</script>
//结果
r: 123in,123,in
r[0]: 123in
r[1]: 123
r[2]: in
r[0][0]: 1
r[1][0]: 1
r[1][1]: 2
r[1][2]: 3
r: 345ian,345,ian
r[0]: 345ian
r[1]: 345
r[2]: ian
r[0][0]: 3
r[1][0]: 3
r[1][1]: 4
r[1][2]: 5

r的长度为3,r[0]是所有复合元素的集合,r[1],r[2]是集合中的元素,分别为数字和字母。
3、组合分组

<script>
    //其他均未改变,只改变正则表达式
    //正则表达式
    var reg=/((\d+)([a-z]+))/gi;
</script>
//结果
r: 123in,123in,123,in
r[0]: 123in
r[1]: 123in
r[2]: 123
r[0][0]: 1
r[1][0]: 1
r[1][1]: 2
r[1][2]: 3
r: 345ian,345ian,345,ian
r[0]: 345ian
r[1]: 345ian
r[2]: 345
r[0][0]: 3
r[1][0]: 3
r[1][1]: 4
r[1][2]: 5

通过以上的代码了解到,分组其实就是把()内符合条件的都单独存放在一个数组中,一层层包含。组合分组最大,接下来是第一个分组,第二个分组,第三个分组。。。那么他们究竟有什么用呢?
4、案例分析
所有的操作系统都有一个搜索功能,现在需要用js来实现查找文件后缀为doc的文档。

<script>
    var str="test01.doc,test02.doc,js_01.txt,js_02.txt,web01.html,web02.html";
    var reg=/(\w+)\.([a-z]+)/gi;
    //输出
    while((r=reg.exec(str))!=null){
        document.write("r:  "+r+"<br/>");
        if(r[2]=="doc"){
            document.write("所有doc文档的名字:"+r[1]+"<br/>");
        }
    }
</script>
//结果
所有doc文档的名字:test01
所有doc文档的名字:test02

5、总结
分组是一个很重要而且很常见的使用。需要重点掌握。

候选

1、( | )

<script>
    //字符串
    var str="done is better 2015";
    //正则表达式
    var reg=/(\w+|\d+)/gi;
    //输出
    while((r=reg.exec(str))!=null){
        document.write(r+"<br/>");
    }
</script>
//结果
done,done
is,is
better,better
2015,2015

还是分组,|意为或
2、[ | ]

<script>
    //其他均未改变,只改变正则表达式
    //正则表达式
    var reg=/[\w+|\d+]/gi;
</script>
//结果
d
o
n
e
i
s
b
e
t
t
e
r
2
0
1
5

没有进行分组,每次都是输出一个单个的字符。

反向引用

表达式计算完的每个分组(按照括号从左到右的顺序)被存储在RegExp构造函数中,通过$n获取。

<script>
    //字符串
    var str="123 is 456 2015";
    //正则表达式
    var reg=/(\d+)/gi;
    //必须先执行一次正则表达式,执行完后,正则表达式中一个数组中存储了满足条件的值
    reg.test(str);
    //输出
    document.write(RegExp.$1);
</script>
//结果
123

(?:分组条件)

在分组时,捕获到数据后,不做存储.。
匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。

<script>
    //字符串
    var str="dona is donb 2015";
    //正则表达式
    var reg=/don(?:a|b)/gi;
    //输出
    while((r=reg.exec(str))!=null){
        document.write(r+"<br/>");
    }
</script>
//结果
dona
donb

js正则表达式的几个案例:

1、反向引用

<script>
    //字符串
    var str="1-张三,2-李四,3-王五";
    //正则表达式
    var reg2=/(\d)+-([\u4e00-\u9fa5]+)?/gi;
    //反向显示这个字符
    document.write(str.replace(reg2,"$2-$1"));
</script>
//结果
张三-1,李四-2,王五-33
<script>
    //字符串
    var str="湘C22222 湘D33333 湘C44444 湘C55555 湘C66666 湘C77777 湘C88888 湘C12345 湘C34445";
    //正则表达式 靓牌
    //匹配后面为重复数字的车牌
    var Reg1=/([\u4e00-\u9fa5]\w(\d{1})\2{4})/gi;
    document.write(str.match(Reg1));
</script>
//结果
湘C22222,湘D33333,湘C44444,湘C55555,湘C66666,湘C77777,湘C88888

2、候选,可用来对网页内容样式的选择

<script>
    var s1="red";
    var s2="black";
    //字符串候选
    var rorb=/(red|black)/;
    document.write(rorb.test(s1)+"<br/>");
    document.write(rorb.test(s2)+"<br/>");
    var str="red is a color,black is another color";
    //字符候选
    var reg=/[red|black]/gi;
    document.write(str.match(reg));
</script>
//结果
true
true
r,e,d,a,c,l,r,b,l,a,c,k,a,e,r,c,l,r

3、分组 对数据的一个校正

<script>
    //旧图书编号5位数字 新图书编号5位数字-4位编号
    var bookbsn="10101,10102,10103-0001,10104-0002,10104-0003";
    //分成三组
    var reg=/(\d{5})(-(\d{4}))?/gi;
    bookbsn.match(reg);
    var index=0;
    var i;
    var arr=new Array();
    //分组 第一组:(\d{5}) 第二组加- 第三组不加-
    //
    while((r=reg.exec(bookbsn))!=null){
        if(r[2]==null||r[2]==''){
            arr[index++]=r[1];
        }else{
            arr[index++]=r[3];
        }
    }
    document.write(arr);
</script>
    //结果
    10101,10102,0001,0002,0003

总结

javascript是一门很“活泼”的语言,驾驭的好可以做出很多有趣,很方便的东西,正则表达式相对于java,python来说,js更难一点。
通过js我们可以快速的验证一个用户名,密码,重复密码,电话号码,区号,邮箱,地址等等格式正确与否,不需要通过和服务器进行交换数据,就能很方便的校验,一个可以减少数据库的压力,另一方面可以提高用户体验,实乃神器。

做一只大海中的小鱼

发布了37 篇原创文章 · 获赞 63 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章