JavaScript必会妙技——正则表达式

正则表达式是什么

RegExp 对象示意正则表达式,它是对字符串实行形式婚配的壮大东西。

为何应用正则表达式

  • 测试字符串内的形式。比方,能够测试输入字符串,以检察字符串内是不是涌现电话号码形式或信用卡号码形式。这称为数据考证。

  • 替代文本。能够应用正则表达式来辨认文档中的特定文本,完整删除该文本或许用其他文本替代它。

  • 基于形式婚配从字符串中提取子字符串。能够查找文档内或输入域内特定的文本。

语法

正则表达式有两种要领定义:

1.直接量语法

/pattern/attributes

2.建立 RegExp 对象的语法:

new RegExp(pattern, attributes);

参数:参数pattern是一个字符串,指定了正则表达式的形式;参数attributes是一个可选的参数,包含属性g,i,m,离别应用与全局婚配,不辨别大小写婚配,多行婚配;
返回值:一个新的RegExp对象,具有指定的形式和标志;

润饰符

润饰符申明
g实行全局婚配(查找一切婚配而非在找到第一个婚配后住手)。
i实行不分大小写婚配。
m实行多行婚配。

括号

方括号包含一系列字符,能够婚配它所包含的恣意字符;同时能够经由过程^标记来定义否认字符类

表达式申明
[abc]查找在方括号中的恣意一个字符
[^abc]查找不在方括号中的恣意一个字符
[0-9]查找0-9中的恣意一个数字
[a-z]查找任何从小写 a 到小写 z 的字符
[A-Z]查找任何从大写 a 到大写 z 的字符
(red | blue | green)查找小括号中的恣意一项,小括号中的|是或许的意义

元字符

元字符申明
.查找恣意的单个字符,除换行符和其他Unicode行终止符以外
\w查找字母数字和下划线 ,等价于[a-zA-Z0-9_]
\W查找除字母数字下划线以外的字符,等价于[^a-zA-Z0-9_]
\d查找数字字符,等价于[0-9]
\D查找非数字字符,等价于[^0-9]
\s婚配任何空缺字符,包含空格,制表符,换行符等等。等价于[\f\n\r\t\v]
\S婚配任何非空缺字符,等价于[^\f\n\r\t\v]
\b查找一个单词边境,也就是指单词和空格间的位置,比方er\b能够婚配”never”中的”er”,然则不能婚配”verb”中的”er”
\B查找非单词边境,er\B能婚配”ver”中的”er”,但不能婚配”never”中的”er”
\0查找空字符("")
\n查找换行符
\r查找回车符
\f查找换页符
\t查找制表符
\v查找垂直制表符

量词

量词申明
n+婚配任何最少包含一个n的字符串,等价于n{1,}
n*婚配零个或许多个n的字符串,等价于n{0,}
n?婚配零个或许1个n的字符串,等价于n{0,1}
n{x}婚配包含x个n的序列字符串
n{x,y}婚配最少x个,最多y个n的字符串
n{x,}婚配最少x个n的字符串
n$婚配以n末端的字符串
^n婚配以n开首的字符串

正则表达式的特别字符中须要转义字符

正则表达式中的特别字符都有它们的特别寄义,所以当我们要婚配这些特别字符自身时,须要对字符举行转义,转义只须要在字符前面加上\,这些特别字符包含$ ^ * + . [ ? { | ( ) \

支撑正则表达式的要领

RegExp 对象要领

1.test要领:该要领用于检测一个字符串是不是婚配某个形式。

语法RegExpObject.test(str)
参数:str是须要检测的字符串
返回值:如果字符串str中含有与RegExpObject婚配的文本的话,返回true,不然返回false

示例代码以下:

var str = "longen and yunxi";
console.log(/longen/.test(str)); // true
console.log(/longlong/.test(str)); //false

2.exec要领:该要领用于检索字符串中的正则表达式的婚配。

语法RegExpObject.exec(str)
参数:str是须要检测的字符串
返回值:返回一个数组,寄存婚配的效果,如果未找到婚配,则返回值为null

示例代码以下:

var str = "javascript html css";
console.log(/html/.exec(str)); // ["html", index: 11, input: "javascript html css"]
返回的数组的第一个元素是与正则表达式相婚配的文本,该要领还返回2个属性,index属性声明的是婚配文本的第一个字符的位置;input属性则寄存的是被检索的字符串string。

// 如果没有找到的话,则返回null
console.log(/node/.exec(str)); // null

支撑正则表达式的 String 对象的要领

1.search要领:该要领用于检索字符串中指定的子字符串,或检索与正则表达式相婚配的字符串。

语法stringObject.search(regexp)
参数:regexp能够是在stringObject中检索的字符串,也能够是须要检索的RegExp对象
返回值:stringObject中第一个与regexp对象相婚配的子串的肇端位置。如果没有找到任何婚配的子串,则返回-1;

示例代码以下:

var str = "hello world,hello world";
// 返回婚配到的第一个位置
console.log(str.search(/hello/)); // 0
// search要领不实行全局婚配,它将疏忽标志g,同时它也没有regexp对象的lastIndex的属性,且老是从字符串最先位置举行查找,老是返回的是stringObject婚配的第一个位置。
console.log(str.search(/hello/g)); //0
console.log(str.search(/world/)); // 6

// 也能够是检索字符串中的字符
console.log(str.search("wo")); // 6

// 如果没有检索到的话,则返回-1
console.log(str.search(/longen/)); // -1

// 我们检索的时刻 能够疏忽大小写来检索
var str2 = "Hello";
console.log(str2.search(/hello/i)); // 0

2.match要领:该要领用于在字符串内检索指定的值,或找到一个或许多个正则表达式的婚配。该要领类似于indexOf()或许lastIndexOf(); 然则它返回的是指定的值,而不是字符串的位置。

语法stringObject.match(regexp)
参数:regexp能够是在stringObject中检索的字符串,也能够是须要检索的RegExp对象
返回值:寄存婚配胜利的数组;如果没有找到任何的一个婚配,那末它将返回的是null。

示例代码以下:

var str = "hello world";
// 返回的数组内有三个元素,第一个元素的寄存的是婚配的文本,另有二个对象属性;index属性表明的是婚配文本的肇端字符在stringObject中的位置;input属性声明的是对stringObject对象的援用;
console.log(str.match("hello")); // ["hello", index: 0, input: "hello world"]
console.log(str.match("Hello")); // null
console.log(str.match(/hello/)); // ["hello", index: 0, input: "hello world"]

// 全局婚配也返回一个数组,但有些不一样;它的数组元素中寄存的是 stringObject 中一切的婚配子串,而且也没有 index 属性或 input 属性。
var str2="1 plus 2 equal 3"
console.log(str2.match(/\d+/g)); //["1", "2", "3"]

3.replace要领:该要领用于在字符串中应用一些字符替代另一些字符,或许替代一个与正则表达式婚配的子字符串。

语法stringObject.replace(regexp/substr,replacement);
参数:regexp/substr能够是字符串或许是须要替代形式的RegExp对象;replacement能够是替代的文本或许是天生替代文本的函数。
返回值:返回替代后的新字符串。

字符串 stringObject 的 replace() 要领实行的是查找并替代的操纵。它将在 stringObject 中查找与regexp 相婚配的子字符串,然后用 replacement 来替代这些子串。如果 regexp 具有全局标志 g,那末replace() 要领将替代一切婚配的子串。不然,它只替代第一个婚配子串。

replacement能够是字符串,也能够是函数。如果它是字符串,那末每一个婚配都将由字符串替代。然则 replacement 中的 $字符具有特定的寄义。以下表所示,它申明从形式婚配获得的字符串将用于替代。

字符寄义
$1$2、…、$99与 regexp 中的第 1 到第 99 个子表达式相婚配的文本。
$&与 regexp 相婚配的子串。
$`位于婚配子串左边的文本。
$'位于婚配子串右边的文本。
$$示意美圆标记$。

示例代码以下:

var str = "hello world";
// 应用字符串替代字符串
var s1 = str.replace("hello","a");
console.log(s1);// a world

// 应用正则替代字符串
var s2 = str.replace(/hello/,"b");
console.log(s2); // b world

// 应用正则全局替代字符串
var s3 = str.replace(/l/g,'');
console.log(s3); // heo word

// $1,$2 代表的是第一个和第二个子表达式相婚配的文本
// 子表达式须要应用小括号括起来,代表的寄义是分组
var name = "longen    ,yunxi";
var s4 = name.replace(/(\w+)\s*,\s*(\w+)/,"$2 $1");
console.log(s4); // "yunxi,longen"

console.log('hello world'.replace(/w/g, '$&')) //hello world
console.log('hello world'.replace(/w/g, '$$')) //hello $orld
console.log('hello world'.replace(/w/g, '$`')) //hello hello orld
console.log('hello world'.replace(/w/g, "$'")) //hello orldorld

// replace 第二个参数也能够是一个function 函数
// 单词首字母大写
var name = 'aaa bbb ccc';
var uw=name.replace(/\b\w+\b/g, function(word){
    return word.substring(0,1).toUpperCase()+word.substring(1);}
);
console.log(uw) //Aaa Bbb Ccc


var name2 = "123cbc45678rtyu909876pjkl54321";
name2.replace(/\d+/g,function(v){
    console.log(v); 
    /*
     * 第一次打印123
     * 第二次打印45678
     * 第三次打印909876
     * 第四次打印54321
     */
});
/*
 * 以下函数,回调函数参数一共有四个
 * 第一个参数的寄义是 婚配的字符串
 * 第二个参数的寄义是 正则表达式分组内容,没有分组的话,就没有该参数,
 * 如果没有该参数的话那末第四个参数就是undefined
 * 第三个参数的寄义是 婚配项在字符串中的索引index
 * 第四个参数的寄义是 原字符串
 */
 name2.replace(/(\d+)/g,function(a,b,c,d){
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(d);
    /*
     * 如上会实行四次,值离别以下(正则应用小括号,代表分组):
     * 第一次: 123,123,0,123cbc45678rtyu909876pjkl54321
     * 第二次: 45678,45678,6,123cbc45678rtyu909876pjkl54321
     * 第三次: 909876,909876,15,123cbc45678rtyu909876pjkl54321
     * 第四次: 54321,54321,25,123cbc45678rtyu909876pjkl54321
     */
 });

4.split要领:该要领把一个字符串支解成字符串数组。

语法stringObject.split(separator,howmany)
参数
1.separator[必填项],字符串或正则表达式,该参数指定的处所支解stringObject;
2.howmany[可选] 该参数指定返回的数组的最大长度,如果设置了该参数,返回的子字符串不会多于这个参数指定的数组。如果没有设置该参数的话,全部字符串都会被支解,不斟酌他的长度。
返回值:一个字符串数组。该数组经由过程在separator指定的边境处将字符串stringObject支解成子字符串。

示例代码以下:

var str="How are you doing today?"
console.log(str.split(" ")) //["How", "are", "you", "doing", "today?"]
console.log(str.split("")) //["H", "o", "w", " ", "a", "r", "e", " ", "y", "o", "u", " ", "d", "o", "i", "n", "g", " ", "t", "o", "d", "a", "y", "?"]
console.log(str.split(" ",3)) //["How", "are", "you"]

// 也能够应用正则表达式
console.log(str.split(/\s+/)) //["How", "are", "you", "doing", "today?"]

贪欲形式与非贪欲形式

Javascript中的正则表达式贪欲形式与非贪欲形式的区别是:被量词润饰的子表达式的婚配行动;贪欲形式在全部表达式婚配胜利的情况下尽量多的婚配;非贪欲形式在全部表达式婚配胜利的前提下,尽量少的婚配。

一些罕见的润饰贪欲形式的量词以下:
{x,y}{x,}?*+

非贪欲形式就是在如上贪欲形式后加上一个问号(?),就能够变成非贪欲形式的量词;以下:
{x,y}?{x,}???*?,和+?

示例代码以下:

//贪欲形式,尽量多的婚配
console.log('0123456789'.replace(/\d{3,6}/,"*")) //*6789

//非贪欲形式,尽量少的婚配
console.log('0123456789'.replace(/\d{3,6}?/,"*")) //*3456789

分组与反向援用

分组,又称为子表达式。把正则表达式拆分红小表达式。

直接上代码:

//不分组,量词仅作用到末了一个字符(c)
console.log(/abc{2}/.test('abcabc')); // false
console.log(/abc{2}/.test('abcc')); //true

//分组,量词作用于全部括号里的子表达式
console.log(/(abc){2}/.test('abcabc')); // true
console.log(/(abc){2}/.test('abcc')); //false

分组常常和反向援用一同应用,反向援用在前面的replace要领就有了,只不过没有说他的观点,这里说一下:当一个正则表达式被分组后,每一个分组自动被给予一个组号,一左到右离别是 $1 $2…
再举个例子:

//格式化日期
var reg = /^(\d{4})[/-](\d{2})[/-](\d{2})$/
console.log('2016/11/18'.replace(reg, '$1年$2月$3日')) //2016年11月18日
console.log('2016-11-18'.replace(reg, '$1年$2月$3日')) //2016年11月18日
console.log('2016-11-18'.replace(reg, '$1$2$3')) //20161118

非捕捉性分组

不是一切分组都能建立反向援用,有一种分组叫做非捕捉性分组,非捕捉性分组以(?:pattern)示意,在一些只须要分组婚配然则并不须要获得各个分组婚配的效果时,应用非捕捉性分组能够进步婚配速率;非捕捉分组的寄义我们能够理解为以下:子表达式能够作为被团体润饰然则子表达式婚配的效果不会被存储;以下:

var reg = /(?:\d{4})-(\d{2})-(\d{2})/
var date = '2012-12-21'
reg.test(date)
RegExp.$1  // 12
RegExp.$2  // 21

这里,(?:d{4})分组不会捕捉任何字符串,所以$1(d{2})捕捉的字符串。

零宽断言

初学者第一次看到这个名词能够有点懵逼(我第一次也不懂),这里申明一下。

零宽断言就是下结论,比方ab,正则:a(?=b),婚配a而且向右看是b,获得的效果是a,断言不会在婚配的内容当中,如果是a(?=c),则婚配不到任何内容,由于婚配a今后向右看并非c。别的,零宽断言分两种:前瞻(Lookahead)和后顾(Lookbehind);但JavaScript只支撑前瞻

前瞻表达式的语法以下:

表达式申明
m(?=n)婚配背面紧接n的字符串m
m(?!n)婚配背面没有紧接n的字符串m

再两个例子:

// 猎取字符串中以ing末端的单词的前半部份
var str = 'I love dancing but he likes singing';
var pattern = /\b\w+(?=ing\b)/g;
var ans = str.match(pattern);
console.log(ans); // ["danc", "sing"]


// 猎取第五位不是i的单词的前四位
var s = 'I love dancing but he likes singing';
var pattern = /\b\w{4}(?!i)/g;
var ans = s.match(pattern);
console.log(ans); // ["love", "like"]

末了

正则表达式基础知识差不多这些够用了,背面就是多谢多应用。共勉!

引荐

末了引荐两个比较好的东西,能协助我们写出更好更正确的正则表达式。
正则表达式图形化东西
正则表达式检测东西

博客地址

参考

JavaScript RegExp 对象
深入浅出的javascript的正则表达式进修教程

    原文作者:funnyF2E
    原文地址: https://segmentfault.com/a/1190000007602848
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞