常用RegExp元字符

元字符 匹配模型 例子
^ 匹配一个输入或一行的开头, /^a/匹配”an A”,而不匹配”An a”
$ 匹配一个输入或一行的结尾, /a$/匹配”An a”,而不匹配”an A”
* 匹配前面元字符0次或多次, /ba*/将匹配b,ba,baa,baaa
+ 匹配前面元字符1次或多次, /ba*/将匹配ba,baa,baaa
? 匹配前面元字符0次或1次, /ba*/将匹配b,ba
\s 匹配一个空白字符, 包括\n,\r,\f,\t,\v等
\w 匹配包括下划线的任何单词字符。 等价于’[A-Za-z0-9_]’
. .字符可以匹配任何单个的字符、字母、数字甚至是.本身 会匹配字符串中除了换行符\n之外的所有字符

patten修饰符

修饰符 描述
i 执行对大小写不敏感的匹配。
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m 执行多行匹配。

RegExp对象属性

属性 描述
global RegExp 对象是否具有标志 g。
ignoreCase RegExp 对象是否具有标志 i。
lastIndex 一个整数,标示开始下一次匹配的字符位置。
multiline RegExp 对象是否具有标志 m。
source 正则表达式的源文本。

常用RegExp对象方法(3个)

方法 描述
test 检索字符串中指定的值。返回 true 或 false。
exec 检索字符串中指定的值。返回找到的值,并确定其位置。
compile 编译正则表达式。

test

查找对应的字符串中是否存在模式,返回Boolean

var patten = /^hello/;
var str = 'hello world!';
var result = patten.test(str); // true

每次执行test()函数都只查找最多一个匹配,如果找到就立即返回true,否则返回false

如果为正则表达式设置了全局标志(g),test()函数仍然只查找最多一个匹配,不过我们再次调用该对象的test()函数就可以查找下一个匹配。

其原因是:如果regExpObject带有全局标志g,test()函数不是从字符串的开头开始查找,而是从属性regExpObject.lastIndex所指定的索引处开始查找。该属性值默认为0,所以第一次仍然是从字符串的开头查找。当找到一个匹配时,test()函数会将regExpObject.lastIndex的值改为字符串中本次匹配内容的最后一个字符的下一个索引位置。当再次执行test()函数时,将会从该索引位置处开始查找,从而找到下一个匹配。

因此,当我们使用test()函数执行了一次匹配之后,如果想要重新使用test()函数从头开始查找,则需要手动将regExpObject.lastIndex的值重置为 0。如果test()函数再也找不到可以匹配的文本时,该函数会自动把regExpObject.lastIndex属性重置为 0。

notice: test方法慎用/g

var patten = /^[1,9]\d{4,20}$/g;

var str = "123456";

console.log(patten.lastIndex); //0

console.log(patten.test(str)); //true

console.log(patten.lastIndex); //6

console.log(patten.test(str)); //false

console.log(patten.test(str)); //true

console.log(patten.lastIndex); //6

var str2 = '123456';

console.log(patten.test(str2)); //false

console.log(patten.test(str)); //true

看出patten.test(str)执行一次之后patten.lastIndex = 6;

那么下一次再调用 test 的时候, 就会从第6个字符之后继续搜索

解决办法(一),将正则表达式的 lastIndex 属性设置为0

var patten = /^[1,9]\d{4,20}$/g;

var str = "123456";

console.log(patten.lastIndex); //0

console.log(patten.test(str)); //true

console.log(patten.lastIndex); //6

patten.lastIndex = 0

console.log(patten.test(str)); //true

解决办法(二),正则模式去掉全局模式。

var patten = /^[1,9]\d{4,20}$/;

var str = "123456";

console.log(patten.lastIndex); //0

console.log(patten.test(str)); //true

console.log(patten.lastIndex); //0

console.log(patten.test(str)); //true

exec

返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。

var patten = /1./;
var str = "1a1b1c";
var result = patten.exec(str);

console.log(result);  // ["1a", index: 0, input: "1a1b1c"]

console.log(result[0]);  // 1a
console.log(result.index);  // 0
console.log(result.input); // 1a1b1c

exec 方法受参数 g 的影响。

若不指定g,执行两次exec(),返回相同的结果。

非全局匹配模式patten.lastIndex始终都是0

var patten = /1./;
var str = "1a1b1c";

console.log(patten.lastIndex); // 0

var result = patten.exec(str);
console.log(result);  // ["1a", index: 0, input: "1a1b1c"]

console.log(patten.lastIndex); // 0

result = patten.exec(str);
console.log(result);  // ["1a", index: 0, input: "1a1b1c"]

console.log(patten.lastIndex); // 0

在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。

若指定了 g,则下次调用 exec 时,会从上个匹配的 lastIndex 开始查找。

var patten = /1./g;
var str = "1a1b1c";
var result = patten.exec(str);

console.log(patten.lastIndex); // 0

console.log(result);  // ["1a", index: 0, input: "1a1b1c"]
console.log(result[0]);  // 1a
console.log(result.index);  // 0
console.log(result.input); // 1a1b1c

console.log(patten.lastIndex); // 2

result = patten.exec(str);

console.log(result);  // ["1b", index: 2, input: "1a1b1c"]
console.log(result[0]); // 1b
console.log(result.index); // 2
console.log(result.input);  //1a1b1c

console.log(patten.lastIndex);  // 4

exec() 通常和while语句配合使用

var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = 'Found ' + myArray[0] + '. ';
  msg += 'Next match starts at ' + myRe.lastIndex;
  console.log(msg);
}

result:

1
2
Found abb. Next match starts at 3
Found ab. Next match starts at 9

小节:RegExp的两个方法,模式匹配中的全局修饰符g, 相当于,执行时每次 patten.lastIndex 的值是否改变。

  • RegExpObj.test(str) , patten 要慎用g;
  • RegExpObj.exec(str) , patten 需要g修饰,才能显出exec() 的强大。

支持正则表达式的String对象的方法(4个)

方法 描述
match 找到一个或多个正则表达式的匹配。
replace 替换与正则表达式匹配的子串。
search 检索与正则表达式相匹配的值。
split 把字符串分割为字符串数组。

match

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。

返回值

存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。

如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。

如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。

注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。

匹配字符串

var patten1 = "hello";
var patten2 = "HELLO";

var str = "hello world";

var result1= str.match(patten1)
var result2= str.match(patten2)

console.log(result1); // ["hello", index: 0, input: "hello world"]
console.log(result1[0]); // hello
console.log(result1.index); // 0

console.log(result2); // null

match正则

var patten = /1./;

var str = "1a1b1c";
var result  = str.match(patten)

console.log(result); // ["1a", index: 0, input: "1a1b1c"]
console.log(result[0]); // 1a

全局匹配

var patten = /\d+/g;

var str = "1 plus 2 equal 3";

var result= str.match(patten)


console.log(result); // ["1", "2", "3"] 
console.log(result[0]); // 1

replace

定义和用法

replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

语法

str.replace(regexp|substr, newSubstr|function)
str.replace(regexp|substr, newSubStr|function[, flags]);

参数介绍:

1)参数一:
a)regexp:一个 RegExp 对象.该正则所匹配的内容会被第二个参数的返回值替换掉.
b)substr:被替换掉的一个 String.

2)参数二:

  • a) newSubStr:替换掉第一个参数在原字符串中的匹配部分.该字符串中可以内插一些特殊的变量名. 比如
字符 替换文本
$1、$2、…、$99 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。
$& 与 regexp 相匹配的子串。
$` 位于匹配子串左侧的文本。
$’ 位于匹配子串右侧的文本。
$$ 直接量符号。
  • b) function(str,$1[,$2,…,$99],offset,s):创建新的子串,参数解释如下

str:匹配的子串
$1…99:第n个括号子匹配字符串,提供替换的第一个参数是一个正则表达式对象。(对应于$1、$2等。)
offset:匹配子串在字符串中的开始位置(从0开始),例如”abcd”,正则/bc/,offset = 1.
s:当前操作的字符串

3)参数三(可选):
flags:指定正则表达式的匹配模式,可选值:
g:全局替换
i:忽略大小写
m:多行替换
y:?

str.replace(regexp, newSubstr)

var str = 'Twas the night before Xmas...';
var newstr = str.replace(/xmas/i, 'Christmas');
console.log(newstr);  // Twas the night before Christmas...

str.replace(regexp, function(match))

var a = "The quick brown fox jumped over the lazy dog.";

var pattern = /quick|brown|lazy/ig;

a.replace( pattern, function replacer(match){
    return match.toUpperCase();
} );
function test(string) {
	return string.replace(/-([\w])/gi,function(match){
		return "**"+match+"##";
	})
}
var string = "margin-left-right";
console.log(test(string)); // margin**-l##eft**-r##ight

str.replace(regexp, function(match,$1…))

function replacer(match, p1, p2, p3, offset, string) {
  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
  return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString);  // abc - 12345 - #$*%

split

RegExp分组

括号() ,表示子表达式,也叫分组

var patten = /(\w)(\w)/;
var str='zhufengpeixun';

var result = patten.exec(str)

console.log(result)  //["zh", "z", "h", index: 0, input: "zhufengpeixun"]
console.log(result[0]) //zh

返回zh,z,h ,zh是整个正则匹配的内容,z是第一个括号里的子正则表达式匹配的内容,h是第二个括号匹配的内容。

RegExp贪婪匹配和非贪婪匹配

人都是贪婪的,正则也是如此。所有的正则,只要在合法的情况下,它们会尽量多去匹配字符,这就叫做贪心模式。

reg = /c{3,4}/;
str='ccccTest';
reg.exec(str) //cccc

如果我们希望正则尽量少地匹配字符,那么就可以在表示数字的符号后面加上一个?(即:问号加在量词的后边,则表示非贪婪匹配)。组成如下的形式:

{n,}?, *?, +?, ??, {m,n}?

非贪婪

reg = /c{1,}?/;
str='ccccc';
 alert(reg.exec(str)); //c

正则demo

email检查

function emailValid(email) {
	let reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
	return reg.test(email);
}

外文转English

function turnName(name) {
    return name.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
}

更多-more