正则表达式入门教程

Daotin 于 2018-11-12 发布 编辑
  1. 目录

1、正则表达式

正则表达式(regular expression)是一个描述字符规则的对象。

2、正则表达式的作用

前端往往有大量的表单数据校验的工作,采用正则表达式会使得数据校验的工作量大大减轻,如邮箱验证,手机号码,等等。比起用字符串的函数来判断简单,易用。

3、正则表达式的定义

JS 中定义正则表达式有两种方式,一种是通过构造函数,一种是通过/…/,也就是两个斜杠。

3.1、方式一

// 使用RegExp这个对象(构造函数)
// 语法
// pattern: 模板字符串
// attributes:字符串,可选。包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数

var reg = new RegExp(pattern, [attributes]);

//例如:
var reg= new RegExp(study);    //表示含有study,(默认区分大小写)
var reg = new RegExp('study', 'ig'); // 其中i 表示忽略大小写,g 表示全局匹配

3.2、方式二

// 使用常量方式直接声明
//语法
var reg = /study/;
//等价于:var reg= new RegExp('study');
//等价于:var reg= new RegExp(/study/);

4、正则表达式的使用

使用正则表达式来测试某个字符串是否符合正则表达式所规定的规则。

正则表达式可以被用于 RegExp 的exectest方法以及 String 的matchreplacesearchsplit方法。

match:一个在字符串中执行查找匹配的 String 方法,它返回一个数组或者在未匹配到时返回 null。

var s = "_x_x";
var r1 = /x/g;
var r2 = /y/;

s.match(r1); // ["x","x"]
s.match(r2); // null

search:一个在字符串中测试匹配的 String 方法,它返回匹配到的位置索引,或者在失败时返回-1。

"_x_x".search(/x/); // 1

replace:一个在字符串中执行查找匹配的 String 方法,并且使用替换字符串替换掉匹配到的子字符串。

"aaa".replace("a", "b"); // "baa"
"aaa".replace(/a/, "b"); // "baa"
"aaa".replace(/a/g, "b"); // "bbb"

// 清除字符串首尾空格
var str = "  #id div.class  ";
str.replace(/^\s+|\s+$/g, "");

split:一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。

// 非正则分隔
"a,  b,c, d".split(",");
// [ 'a', '  b', 'c', ' d' ]

// 正则分隔,去除多余的空格
"a,  b,c, d".split(/, */);
// [ 'a', 'b', 'c', 'd' ]

// 指定返回数组的最大成员个数为2个
"a,  b,c, d".split(/, */, 2)[("a", "b")];

5、正则表达式属性和方法

5.1、实例属性

// 一类是修饰符相关,返回一个布尔值,表示对应的修饰符是否设置。
RegExp.prototype.ignoreCase; //返回一个布尔值,表示是否设置了i修饰符。
RegExp.prototype.global; //返回一个布尔值,表示是否设置了g修饰符。
RegExp.prototype.multiline; //返回一个布尔值,表示是否设置了m修饰符。

//示例
var r = /abc/gim;
r.ignoreCase; // true
r.global; // true
r.multiline; // true

// 另一类是与修饰符无关的属性
RegExp.prototype.lastIndex; //返回一个整数,表示下一次开始搜索的位置。该属性可读写,但是只在进行连续搜索时有意义,详细介绍请看后文。
RegExp.prototype.source; //返回正则表达式的字符串形式(不包括反斜杠),该属性只读。

//示例
var r = /abc/gim;
r.lastIndex; // 0
r.source; // "abc"

5.2、实例方法

RegExp.prototype.test()

描述:正则实例对象的 test 方法返回一个布尔值,表示当前模式是否能匹配参数字符串。 语法:regexObj.test(str) 参数:str 用来与正则表达式匹配的字符串 返回值:如果正则表达式与指定的字符串匹配 ,返回true;否则false

示例:

/cat/.test("cats and dogs"); // true

RegExp.prototype.exec()

描述:正则实例对象的exec方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回null

语法:regexObj.exec(str)

参数:str 要匹配正则表达式的字符串。

返回值:如果匹配成功,exec() 方法返回一个数组,并更新正则表达式对象的属性。返回的数组将完全匹配成功的文本作为第一项,将正则括号里匹配成功的作为数组填充到后面。如果匹配失败,exec() 方法返回 null。

示例:

var s = "_x_x";
var r1 = /x/;
var r2 = /y/;

r1.exec(s); // ["x"]
r2.exec(s); // null

6、特殊字符

^ // 匹配一行的开头,/^a/匹配"abc",而不匹配“bca“
$ // 匹配一行的结尾,/a$/匹配“bca",而不匹配"abc"

* // 匹配前面元字符0次或多次,/ba*/将匹配b,ba,baa,baaa ,相当于{0,}
+ // 匹配前面元字符1次或多次,/ba+/将匹配ba,baa,baaa ,相当于 {1,}
? // 匹配前面元字符0次或1次,/ba?/将匹配b,ba ,相当于{0,1}

x|y  // 匹配x或y ,/a|b/ 将匹配只要出现a或者b的字符串,不含a与b的不匹配

{n}  // 精确匹配n次 ,/d{4}/  将匹配,出现连续4个d的字符串
{n,} // 匹配n次以上 ,/d{4,}/将匹配,出现连续4个及4个以上的d的字符串
{n,m} // 匹配n-m次,/d{4,8}/将匹配,出现连续4到8个d的字符串




\d //匹配0-9之间的任一数字,相当于[0-9]。
\D //匹配所有0-9以外的字符,相当于[^0-9]。
\w //匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]。
\W //除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]。
\s //匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]。
\S //匹配非空格的字符,相当于[^ \t\r\n\v\f]。
\b //匹配词的边界。
\B //匹配非词边界,即在词的内部。

示例
// \s 的例子
/\s\w*/.exec('hello world')    // [" world"]

// \b 的例子
/\bworld/.test('hello world') // true
/\bworld/.test('hello-world') // true
/\bworld/.test('helloworld') // false

// \B 的例子
/\Bworld/.test('hello-world') // false
/\Bworld/.test('helloworld') // true

7、转义字符(量字符)

\f     换页符
\n     换行符
\r     回车
\t     制表符
\v     垂直制表符
\/     一个 / 直接量
\\     一个 \ 直接量
\.     一个 . 直接量
\*     一个 * 直接量
\+     一个 + 直接量
\?     一个 ? 直接量
\|     一个 | 直接量
\(     一个 ( 直接量
\)     一个 ) 直接量
\[     一个 [ 直接量
\]     一个 ] 直接量
\{     一个 { 直接量
\}     一个 } 直接量

8、方括号

[abc]               //查找abc中的任意一个字符。
[^abc]              //查找除abc的一个字符。
[0-9]               //查找任何从 0 至 9 的数字。
[a-z]               //查找任何从小写 a 到小写 z 的字符。
[adgk]              //查找给定集合内的任何一个字符。
(aa|ddd|gg|kkkk)    // 同上,选取aa,ddd,gg,kkkk中的一个
// 示例:
// [a-z]*表示任意个 a-z 中的字符,[0-9]*表示任意个 0-9 的字符
var pattern = /g[a-zA-Z]*gle/; //[a-z]*表示任意个 a-z 中的字符
var str = "google";
alert(pattern.test(str)); //true
str = "go12agle";
alert(pattern.test(str)); //false
str = "ggle";
alert(pattern.test(str)); //true
var pattern = /g[0-9]*gle/; //[0-9]*表示任意个 0-9 的字符

// 加上^ 表示非(即排除)
var pattern = /g[^0-9]*gle/; //[^0-9]*表示任意个非 0-9 的字符
var str = "google";
alert(pattern.test(str)); //true
str = "g12gle";
alert(pattern.test(str)); //false
str = "ggle";
alert(pattern.test(str)); //true

9、组匹配

正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。

/fred+/.test("fredd") / // true
  fred +
  /.test('fredfred') / / true;

上面代码中,第一个模式没有括号,结果+只表示重复字母d,第二个模式有括号,结果+就表示匹配fred这个词。

var m = "abcabc".match(/(.)b(.)/);
// m = ['abc', 'a', 'c']

10、常用正则表达式

检查邮政编码//共 6 位数字,第一位不能为 0
/^[1-9]\d{5}$/
检查文件压缩包  //xxx.zip\xxx.gz\xxx.rar
/^\w+\.(zip|gz|rar)$/
删除多余空格  //
str.replace(/\s+/,'');
删除首尾空格
str.replace(/^\s+/,''); //去除开头的空格
str.replace(/\s+$/,'');  // 去除结尾的空格
//删除所有的空格
str.replace(/\s/g,'');
//删除前后的空格
str.replace((^\s+)|(\s+$),'')

电子邮件( xxxxx @ xxxx(.xxxx)+)
/^\w+@\w+(\.\w+)+$/
 770107@qq.com; 770107@qq.com.cn
手机号(1开头任意数字)  1(3|5|7|8|4)\d{9}
/^1\d{10}$/

身份证
/^\d{17}(\d|X)$/
  422422 19660101 5810
  421087 19890101 121X
^[1-9]\d{5}[19|20]\d{2}\d{7}(\d|X)$
日期  (合法日期格式xxxx-xx-xx或 xxxx/xx/xx或xxxx.xx.xx)
/^\d{4}[-\/\.]\d{2}[-\/\.]\d{2}$/
只能输入中文
str.replace(/[^\u4e00-\u9fa5]/g,'');
账户名只能使用数字字母下划线且数字不能开头长度在6-15之间
/^[a-zA-Z_]\w{5,14}$/
验证IP
(xxx.)xxx.xxx.xxx|
254.245.255.255
240.196.19.5
/^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/


将所有的bagbegbig和bog改为bug
str.replace(/(bag|beg|big|bog)/g,'bug');

将所有方法foo(a,b,c)的实例改为foo(b,a,c)
str.replace(/foo\(([^,]+),([^,]+),([^,]+)\)/g,'foo($2,$1,$3)');

假设有一个多字符的片断重复出现例如
Billy tried really hard
Sally tried really really hard
Timmy tried really really really hard
Johnny tried really really really really hard
而你想把"really""really really"以及任意数量连续出现的"really"字符串换成一个简单的"very“

str.replace(/(really\s)+/gi,'very');

字符参考

字符 描述
^ 匹配输入的开始。如果多行标志被设置为 true,那么也匹配换行符后紧跟的位置。
$ 匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置。
\w 匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]。 例如,/\w/ 匹配 “apple,” 中的 ‘a’,”$5.28,”中的 ‘5’ 和 “3D.” 中的 ‘3’。
\W 匹配一个非单字字符。等价于 [^A-Za-z0-9_]。 例如,/\W/ 或者 /[^A-Za-z0-9_]/ 匹配 “50%.” 中的 ‘%’。
\d 匹配一个数字。等价于 [0-9]。 例如, /\d/ 或者 /[0-9]/ 匹配”B2 is the suite number.”中的’2’。
\D 匹配一个非数字字符。等价于 [^0-9]。 例如, /\D/ 或者 /[^0-9]/ 匹配”B2 is the suite number.”中的’B’ 。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
\S 匹配任何非空白字符。
\n 匹配一个换行符。
\r 匹配一个回车符。
\f 匹配一个换页符。
\t 匹配一个制表符。
\v 匹配一个垂直制表符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。
\B 匹配非单词边界。
+ 匹配前面一个表达式 1 次或者多次。等价于 {1,}。
* 匹配前一个表达式 0 次或多次。等价于 {0,}。
? 匹配前面一个表达式 0 次或者 1 次。等价于 {0,1}。
. (小数点)默认匹配除换行符之外的任何单个字符。
{n} n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。比如, /a{2}/ 不会匹配“candy”中的’a’,但是会匹配“caandy”中所有的 a,以及“caaandy”中的前两个’a’。
{n,} n 是一个正整数,匹配前一个字符至少出现了 n 次。例如,/a{2,}/ 匹配 “aa”, “aaaa” 和 “aaaaa” 但是不匹配 “a”。
{n,m} n <= m。最少匹配 n 次且最多匹配 m 次。
(x) 它会匹配 ‘x’ 并且记住匹配项。其中括号被称为捕获括号。在正则表达式的替换环节,则要使用像 $1、$2、…、$n 这样的语法,例如,’bar foo’.replace(/(…) (…)/, ‘$2 $1’)。$& 表示整个用于匹配的原字符串。
(?:x) 匹配 ‘x’ 但是不记住匹配项。这种括号叫作非捕获括号,使得你能够定义与正则表达式运算符一起使用的子表达式。看看这个例子 /(?:foo){1,2}/。如果表达式是 /foo{1,2}/,{1,2} 将只应用于 ‘foo’ 的最后一个字符 ‘o’。如果使用非捕获括号,则 {1,2} 会应用于整个 ‘foo’ 单词。
x(?!y) 仅仅当’x’后面不跟着’y’时匹配’x’,这被称为正向否定查找。 例如,仅仅当这个数字后面没有跟小数点的时候,/\d+(?!\.)/ 匹配一个数字。正则表达式/\d+(?!\.)/.exec(“3.141”) 匹配‘141’而不是‘3.141’
x|y 匹配 x 或 y。 例如,/green|red/匹配“green apple”中的‘green’和“red apple”中的‘red’
[xyz] 一个字符集合。匹配方括号中的任意字符,包括转义序列。你可以使用破折号(-)来指定一个字符范围。对于点(.)和星号(*)这样的特殊符号在一个字符集中没有特殊的意义。他们不必进行转义,不过转义也是起作用的。 例如,[abcd] 和 [a-d] 是一样的。他们都匹配”brisket”中的‘b’,也都匹配“city”中的‘c’。/[a-z.]+/ 和/[\w.]+/与字符串“test.i.ng”匹配。
[^xyz] 一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可以使用破折号(-)来指定一个字符范围。任何普通字符在这里都是起作用的。 例如,[^abc] 和 [^a-c] 是一样的。他们匹配”brisket”中的‘r’,也匹配“chop”中的‘h’。
[a-z] 匹配指定范围内的任意字符。

检验字符参考

   
汉字 ^[\u4e00-\u9fa5]{0,}$
英文和数字 ^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为 3-20 的所有字符 ^.{3,20}$
由 26 个英文字母组成的字符串 ^[A-Za-z]+$
由 26 个大写英文字母组成的字符串 ^[A-Z]+$
由 26 个小写英文字母组成的字符串 ^[a-z]+$
由数字和 26 个英文字母组成的字符串 ^[A-Za-z0-9]+$
由数字、26 个英文字母或者下划线组成的字符串 ^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线 ^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号 ^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&’,;=?$\“等字符 [^%&’,;=?$\x22]+