js 正则表达式

在开始正则表达式之前,这里出个题给大家思考,看看大家都有哪些解决思路

问题:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

var str = "汉字a bc;";


好了,言归正传!我们开始js正则表达式

下面是js 中 正则表达式 应该掌握的基本知识简单罗列:

<1> i, m, g

<2> ^, $, \w, \d, \s, \b, .

<3> *, +, ?, {n}, {n,} ,{n,m}

<4> test, exac, match, search, replace, split


///////////////////////////////////////////////////

<1> 
i: 不区分大小写
m: 多行匹配
g: 全局匹配

<2>
^: 首匹配
$: 尾匹配
\w: 字母、数字、下划线 匹配
\d: 数字 匹配
\s: 空白 匹配
\b: 单词首尾  匹配
.: 除换行符外任意字符

<3>
*: 匹配 前一字符 0个或多个
+: 匹配 前一字符 1个或多个
?: 匹配 前一字符 0个或1个
{n}: 匹配 前一字符 n次
{n,}: 匹配 前一字符 至少n次
{n,m}: 匹配 前一字符 n次到m次之间

<4>
test: reg.test(str); // 返回true/false
exec: reg.exec(str); // 以数组的形式返回第一个匹配的值

match: str.match(reg); // 返回数组
search: str.search(reg); // 返回number
replace: str.replace(reg); // 返回字符串
split: str.split(reg); // 返回数组


为了方便理解,这里先讲解各种匹配模式,然后再讲6种方法


一、匹配模式以及正则符号详解

1.简单模式(只通过普通字符的组合来进行匹配)
var reg = /ab0c/;

2.符号^
匹配字符串的起始端

3.符号$
匹配字符串的末尾端

4.符号*
匹配前一个字符0次或多次

5.符号+
匹配前一个字符1次或多次

6.符号?
?的用法比较特殊,一般来说它用来对前一个字符做0次或1次匹配,
但是它有另外两种特殊的用法:
如果紧跟在*、+、?和{ }之后,则表示原始匹配的最小次数匹配

7.符号.
匹配任何一个单独的字符,但是换行符除外

8.符号(x) x指代一个字符串 匹配x,会记住x

var regx=/a(b)c/;
var rs=regx.exec("abcddabcd");
console.log(rs);
从上面可以看出,/a(b)c/匹配“abcddabcd”中的“abc”,因为()的原因,b也会记录下来,
因此rs返回的内容为:{abc,b}

9.符号(?:x) x指代一个字符串 匹配x,不会记住x

var regx=/a(b)c/;
var rs=regx.exec("abcddabcd");
console.log(rs);
从上面可以看出,/a(b)c/匹配“abcddabcd”中的“abc”,因为(?:)的原因,b不会被记录下来,
因此rs返回的内容为:{abc}

10.符号x(?=y) 匹配x,仅当后面紧跟y时。 x会被记住,y不会被记住

var regx=/user(?=name)/;
var rs=regx.exec("The username is Mary");
结果:匹配成功,而且rs的值为{user}

11.符号x(?!y) 匹配x,仅当后面不紧跟着y时。 x会被记住,y不会被记住

var regx=/user(?!name)/;
var rs=regx.exec("The user name is Mary");
结果:匹配成功,而且rs的值为{user}

12.符号x|y 匹配x或y 如果x和y都匹配上了,那么只记住x

var regx=/beijing|shanghai/;
var rs=regx.exec("I love beijing and shanghai");
结果:匹配成功,rs的值为{beijing},虽然shanghai也匹配,但不会被记住。

13.符号{}
{n} 匹配前一个字符n次出现
{n,} 匹配前一个字符至少n次出现
{n,m} 匹配前一个字符至少n次最多m次的出现

14.符号[xyz] xyz表示一个字符串
表示匹配[]中的一个字符,[xyz]等同于[x-z]

15.符号[^xyz] xyz表示一个字符串
表示匹配[]中的一个字符,[^xyz]等同于[^x-z]

16.符号\d  匹配一个数字字符,等同于[0-9]

var regx = /user\d/;
var rs = regx.exec("user145");
console.log(rs);
结果:匹配成功,rs的值为:["user1", index: 0, input: "user145"]
var regx = /user[0-9]+/;
var rs = regx.exec("user145");
console.log(rs);
结果:匹配成功,rs的值为:["user145", index: 0, input: "user145"]

注意二者的区别

17.符号\r  匹配一个回车符

18.符号\s  匹配一个空格符

19.符号\w  匹配一个数字、_或字母表字符 等同于[A-Za-z0-9_]

20.符号\xhh  匹配一个由两位16进制数字所表达的字符

21.符号\uhhhh  匹配由一个四位16进制数字所表达的字符

22.符号[\u4E00-\u9FA5] 匹配中文字符

23.符号[^\x00-\xff] 匹配双字节字符


二、匹配方法

<1> test() 方法:
reg.test(str); // 返回true/false

var str = "12abc678abc2hh";
var reg = /abc/;
console.log(reg.test(str)); //true
reg = /rgy/;
console.log(reg.test(str)); //false
////
<2> exec() 方法:
reg.exec(str); // 以数组的形式返回第一个匹配的值

var str = "12abc678abc2hh";
var reg = /abc/;
console.log(reg.exec(str)); // ["abc", index: 2, input: "12abc678abc2hh"]

////
<3> match() 方法:
str.match(reg); // 返回数组 
若只有一个匹配,则返回-->[匹配的字符串,第一次匹配的index,input]
若匹配了多个,则返回由多个匹配字符串组成的数组,看看下面的例子就明白了

var str = "12abc678abc2hh";
var reg = /abc/;
console.log(str.match(reg));// ["abc", index: 2, input: "12abc678abc2hh"]
var reg = /abc/g;// 全局匹配
console.log(str.);// ["abc", "abc"]


////
<4> search() 方法:
str.search(reg); // 返回number

var str = "12abc678abc2hh";
var reg = /abc/;
console.log(str.search(reg)); // 2
var reg = /abc/g;
console.log(str.search(reg)); // 2
可见 search()只会匹配第一个,并返回其index

////
<5> replace() 方法:
str.replace(reg);// 返回字符串

var str = "12abc678abc2hh";
var reg = /abc/g;
console.log(str.replace(reg, "ABC"));// 12ABC678ABC2hh
console.log(str.replace(/(\d+)([a-z]+)/g, "$2[$1]"));// abc[12]abc[678]hh[2]
后一种属于比较高级的用法,需要好好体会。
(\d+) 和 ([a-z]+) 分别表示两个域,对应于 $1 和 $2,其它的就好理解了


////
<6> split() 方法:
str.split();// 返回由间隔符隔断而形成的数组

var str = "12abc678abc2hh";
console.log(str.split(/[a-z]+/));// ["12", "678", "2", ""]
这里演示了以字符串为间隔形成数组的过程,也体现了正则表达式的强大之处

/////////////////////////////////////////////////////////////////////////

好了,想必大家对一开始提出的问题也有了自己的想法了吧,这里给出用正则表达式解决的方法

String.prototype.len = function(){
	return this.replace(/[^\x00-\xff]/g, "aa").length;
}

var str = "汉字a bc;";
console.log(str.len());// 9


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。