理解javascript正则表达式

了解RegExp类型:

ECMAScript通过RegExp类型来支持正则表达式。 var expression=/pattern/flags;

正则表达式的模式(pattern)部分:

可以是任何简单或复杂的正则表达式,可以包含字符类,限定符,分组,向前查找,反向引用。 关于正则表达式中各种特殊字符(如 \,^,$,\w,\b 等)的含义可以参考 MDN 正则表达式-特殊字符 的整理。这里我们简单介绍一下向前查找和反向引用。

向前查找:正则表达式向前使用一些字符而不移动这些字符的位置,分为正向前预搜索也叫正向肯定查找( x(?=y) )与负向前预搜索也叫正向否定查找( x(?!y) )。
反向引用:标识字符串中可以提供的重复字符或字符串,可以使用捕获组反向引用匹配。带编号的反向引用 \number number是正则表达式中捕获组的序号位置。
1、表达式 \1~\9 解释为反向引用而不是八进制代码。 /\b(\w+)\s\1/.exec('s_ s_');//["s_ s_", "s_"]
2、如果多位表达式的第一个数字是8或者9(如 \80 或 \91 ),则该表达式将被解释为文本。 /\b(\w+)\s\80/.exec('s_ 800');//["s_ 80", "s_"]
3、对于编号为 \10 或更大值的表达式,如果存在与该编号对应的反向引用,则将该表达式视为反向引用。否则将这些表达式解释为八进制。

/(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)xx\10/.exec('12345678910xx10');//["12345678910xx10", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
/(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)xx\11/.exec('12345678910xx10');//null

4、如果捕获组嵌套捕获组,捕获组确定的顺序是内部从外到内,外部从左到右。来个代码体会一下。
/\b(\w+x(x))\s(\1)/.exec('s_xx s_xxSTOP');//["s_xx s_xx", "s_xx", "x", "s_xx"]
5、如果正则表达式包含对未定义的组成员的反向引用,则会发生分析错误,根据语言的不同正则表达式引擎将引发 ArgumentEXception 。对于javascript会返回null。/\b(\w+)\s\2/.exec('s_ 8');//null
反向引用实例代码:捕获组捕获到的内容不仅可以在正则表达式外部通过程序进行引用( RegExp.$n )也可以在正则表达式内部进行引用( \number ,这种引用方式就是反向引用)。

//表达连续三个相同的小写,{2}应用在\1身上
/([a-z])\1{2}/.exec('aaa');//["aaa", "a"]
复制代码
//一道有意思的正则问题
/(\w)((?=\1\1\1)(\1))/.exec('aa bbbb');//["bb", "b", "b", "b"]

/*这里捕获组有三个,$1为(\w)中的内容,$2为((?=\1\1\1)(\1))中的内容:
需注意(?=\1\1\1)并不是捕获组而是正则表达式的判断条件,x(?=y)表示匹配x仅仅当后面跟着y,判断条件并不是匹配结果的一部分。所以现在$2的内容为(\1)即‘b'。$3就是\1的内容。返回的匹配项
“bb”中的第一个'b'为"aa bbbb"中的第一个'b',第二个'b'为"aa bbbb"中的第二个'b'。*/

/(\w)(x(?=\1\1\1)(\1))/.exec('aa bxbbbcb');//["bxb", "b", "xb", "b"]
//这里$2的内容为(x(?=\1\1\1)(\1))中的内容即x(\1);

//其实上面两种模式可以简化成/(\w)(?=\1\1\1)(\1)/表示匹配\w仅当该\w后后面跟着三个\1,然后获取的匹配项为该\w且其后再紧跟着\1的字符串。同理/(\w)x(?=\1\1\1)(\1)/
复制代码
/(\w)((?=\1\1\1)(\2))/.exec('aa bbbbv');//["b", "b", "", ""]
/*捕获组$2为((?=\1\1\1)(\2))中的内容,由于此时还未执行完捕获组$2处的匹配,所以\2表示""。$3即为\2的内容还是""。所以这条匹配被解释为返回\w且其后紧跟3个该\w的字符串,返回\w+''就只返回'b'了。*/

正则表达式的标志位(flags)部分:

可以带有一个或多个标志,用以表明正则表达式的行为。

1、g:表示全局模式,模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止。 'cat mat bat'.replace(/.(?=at)/g,'A');//"Aat Aat Aat"
2、i:不区分大小写模式,在确定匹配项时忽略模式与字符串的大小写。 'cAt mat bAt'.replace(/a/gi,'B');//"cBt mBt bBt"
3、m:多行模式,在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项。

var str='cat\nmat\nbat';
str.replace(/at/gm,'AB');
/*"cAB
mAB
bAB"*/

正则表达式中的元字符部分:

在模式中使用这些元字符时必须转义,如果想要匹配的字符串中包含这些字符,就需要对他们进行转义。

( [ { \ ^ $ | ) ? * + . ] }
//匹配"[bc]at"
/\[bc\]at/.exec("xx[bc]at");//["[bc]at"]

//匹配".at"
/\.at/.exec("xx.at");//[".at"]

创建正则表达式:

字面量形式:形如 var expression=/pattern/flags;
RegExp构造函数:两个参数(要匹配的字符串模式,可选的标志字符串),不能把正则表达式字面量传递给构造函数,虽然即使这样写了也不会报错。可以使用字面量定义的任何表达式都可以使用构造函数来定义。如下:

var p=/[bc]at/;
new RegExp('[bc]at');// /[bc]at/

1、当不传任何参数或参数一为空字符串时, new RegExp();// /(?:)/  或 new RegExp('');// /(?:)/ ,表示匹配 "" 但不记住匹配项( "" 其实就是 ":" 之后的空串,不记住x匹配项的规则为(?:x)),所以在匹配任何字符串时都返回 [""] 。所以由此可以猜想一下javascript正则引擎内部机制应该是默认匹配 "" 且不记住该匹配项,除非显式声明在 ":" 之后的需要匹配的字符串,加上 "(?:)" 显式声明不记住匹配项。
2、由于构造函数模式参数是字符串,所以某些情况下(是指那些已经转义过的字符)对字符进行双重转义(即在字面量形式的单重转义再来一层转义)。某些情况下当然也可以进行单重转移( new RegExp('\w');// /w/ )。注意'\'比较特殊,在字符串中也需要进行转义。

var p=/\\n/;//转义\,字符"\"在字符串中常需要被转义为"\\"
p.exec("\\nxx");//["\n"]

var p=new RegExp("\\\\n");// /\\n/ 如果想获得正则表达式字面量为/\\n/,需要在正则表达式中再来一层转义
p.exec('\\nxx');//["\n"] 注意被匹配的字符串'\nxx'中\n的\也被转义了

new RegExp('\\n').exec("\n");//
["
"]
/*RegExp('\\n')返回/\n/,即意思匹配换行符*/

new RegExp('\n').exec("\n");//
["
"]
/*new RegExp('\n')返回
/
/ ,表示并没有进行转义,而是返回字面量
/
/,意思匹配换行符
*/

3、下面给出一些单重,双重转义模式的参考:第几次转义在表中已标出,单代表第一次转义,双代表在已经有的转义的基础上再进行的转义。

RegExp的实例属性:

通过实例的属性可以获取有关模式的各种信息

global :布尔值,表示是否设置了g标志。
 ignoreCase :布尔值,表示是否设置了i标志。
 multiline :布尔值,表示是否设置了m标志。
 lastIndex :整数,表示开始搜索下一个匹配项的字符位置,从0算起。前提是设置g标志时才会有用。
 source :正则表达式的字符串标志,按照字面量形式而非构造函数中的字符串模式返回字符串。

new RegExp('\\\\w');// /\\w/ 返回自面量形式正则表达式
new RegExp('\\\\w').source;// "\\w" 字符串

RegExp的实例方法:

exec():该方法是专门为捕获组而设计的,参数为要匹配的字符串,返回包含第一个匹配项信息和可能有的捕获组的数组,若未匹配到返回 null 。(返回的虽然是 Array 的实例,但还包含两个额外的属性: index 表示匹配项在字符串中的位置, input 表示应用正则表达式的字符串)

var arr=new RegExp('\\\\(w)').exec('\\w');// ["\w", "w"]
arr;// ["\w", "w"]
arr.index;//0
arr.input;// "\w" 即exec()里的内容

exec() 和 match() 方法的区别:

1、对于 exec() 而言,即使在模式中设置了全局标志g,它每次也只返回一个匹配项;字符串的 match() 方法在设置g的时候可以返回全部匹配项而没有捕获组且返回的数组没有index和input属性。

2、对于exec()而言可以返回捕获组,但match()在没有全局g标志时才能返回捕获组,此时match()返回的数组有index和input属性。

//返回全局匹配项演示比较
var arr='ababcdab'.match(/ab/g);// ["ab", "ab", "ab"]
arr.index; // undefined
arr.input; // undefined
/ab/g.exec('ababcdab');// ["ab"]

//捕获组演示比较,match()方法和有无设置全局g标志有关
'ababcdab'.match(/a(b)/g);// ["ab", "ab", "ab"]
var arr='ababcdab'.match(/a(b)/);// ["ab", "b"]
arr.index;// 0
arr.input;// 'ababcdab'
/a(b)/g.exec('ababcdab');// ["ab", "b"]

3、所以在选择使用方法的时候要先考虑好侧重该方法的哪方面功能,在不设置全局标志g的情况下,在同一个字符串上多次调用exec()则总是返回第一个匹配项的信息,而在设置全局标志的情况下,每次调用exec()则都会在字符串中沿着上次查找的位置往后继续查找新的匹配项。

//未设全局,每次从头开始查找
var p=/a/;
var str='ababa';
var a=p.exec(str);// ["a"];
var b=p.exec(str);// ["a"];
a==b;// false
a.index==b.index;// true

//设置全局,沿着上次位置继续查找新匹配
var p=/a/g;
var str='ababa';
var a=p.exec(str);// ["a"]
a.index;// 0
var b=p.exec(str);// ["a"]
b.index;// 2

test():接收字符串参数,在模式与字符串参数匹配情况下返回 true ,否则返回 false 。常被用在 if() 中当判断条件。

var text="000-000-000";
var p=/((\d{3})-)\1*\2/; if(p.test(text)){
 console.log('匹配成功');
}

RegExp 实例继承 Object 的 toLocaleString() 和 toString() 方法都会返回正则表达式的字面量形式的字符串,与如何创建正则表达式的方式无关。 valueOf() 则返回正则表达式字面量本身。

var p=/\[new\]bi/;
p.toLocaleString();// "/\[new\]bi/"
p.toString();// "/\[new\]bi/"
p.valueOf();// /\[new\]bi/

var p=new RegExp('\\[new\\]bi');
p.toLocaleString();// "/\[new\]bi/"
p.toString();// "/\[new\]bi/"
p.valueOf();// /\[new\]bi/

RegExp的构造函数属性:

构造函数本身包含一些属性(静态属性),这些属性适用于作用域中的所有表达式,并且基于所执行的最近一次正则表达式操作而变化。有长属性名(如下代码)和短属性名(即$前缀形式,由于这些符号大多不是有效的ECMAScript标识符,所以不能直接在 RegExp 构造函数上以 "." 的方式访问,而要通过方括号语法来访问)两种方式访问这些属性

/(.)hort/g.exec('this is a short day');// ["short", "s"]

//最近一次要匹配的字符串
RegExp.input;// "this is a short day" 或RegExp["$_"]访问;

//最近一次的匹配项
RegExp.lastMatch;// "short" 或RegExp["$&"]访问;

//在最近一次要匹配的字符串中的最近一次匹配项之前的文本
RegExp.leftContext;// "this is a " 或RegExp["$`"]访问;

//在最近一次要匹配的字符串中的最近一次匹配项之后的文本
RegExp.rightContext;// " day" 或RegExp["$'"]访问;

//最近一次(最后一次)匹配的捕获组
RegExp.lastParen;// "s" 或RegExp["$+"]访问;

捕获组访问属性:还有9个用于存储捕获组的构造函数属性,访问语法是 RegExp.$n ,其中n取值1~9,用于获取第n个匹配的捕获组。在调用 exec() , test() 或 match() 等正则系列方法时这些属性会被自动填充。

var text="this is a short summer";
var pattern =/(..)or(.)/g;
if(pattern.test(text)){
 console.log(RegExp.$1); // sh
 console.log(RegExp.$2); // t
}

模式的局限性:

缺少一些高级正则表达式的特性,如不支持向后查找,命名的捕获组(形如 \k<name> 引用之前名为 name 的捕获组的字符串)等。

推荐专题 《javascript正则表达式使用说明》

以上就是本文的全部内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • JS只能输入数字或数字和字母等的正则表达式

    JS判断只能是数字和小数点 0.不能输入中文 1)<input onpaste="return false;" type="text" name="textfield" style="width:400px; ime-mode:disabled" value=""> 2) 复制代码 代码如下: <script> function chkIt(frm){ if (frm.n1.valu

  • 比较正宗的验证邮箱的正则表达式js代码详解

    fuchangxi的正则: 复制代码 代码如下: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/ 开始必须是一个或者多个单词字符或者是-,加上@,然后又是一个或者多个单词字符或者是-.然后是点"."和单词字符和-的组合,可以有一个或者多个组合. 复制代码 代码如下: <script type="text/javascript"> function isEmail(str){ var reg =

  • JS正则表达式大全(整理详细且实用)

    正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个单词的边界. -或- 对正则表达式功能字符的还原,如"*"匹配它前面元字符0次或多次,/a*/将匹配a,aa,aaa,加了"\"后,/a\*/将只匹配"a*". ^ 匹配一个输入或一行的开头,/^a/匹配"an A",而不匹配&q

  • js正则表达式中的问号几种用法小结

    在表示重复的字符后面加问号,比如+?,*?,{2,3}?可以停止匹配的贪婪模式. var pattern=/\w{2,3}/; console.log("aaaa".match(pattern)[0]); /*结果"aaa";贪婪模式下会尽可能多的匹配, 所以会匹配3个重复的字符 */ var pattern2=/\w{2,3}?/; console.log("aaaa".match(pattern2)[0]); /* *结果"aa&q

  • js验证电话号码与手机支持+86的正则表达式

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>    <title>正则表达式验证&l

  • JS正则表达式验证数字代码

    复制代码 代码如下: <script type="text/javascript">     function validate(){       var reg = new RegExp("^[0-9]*$");       var obj = document.getElementById("name");    if(!reg.test(obj.value)){        alert("请输入数字!");

  • JS正则表达式获取字符串中特定字符的方法

    实现的效果:在字符串中abcdefgname='test'sddfhskshjsfsjdfps中获取name的值test 实现的机制:通过replace的回调函数获取. 代码: 复制代码 代码如下: var str = "abcdefgname='test'sddfhskshjsfsjdfps"; var reg = /name='((\w|-|\s)+)/ig; str.replace(reg, function() { console.log(arguments.length);

  • js正则表达式中test,exec,match方法的区别说明

    js正则表达式中test,exec,match方法的区别说明 test test 返回 Boolean,查找对应的字符串中是否存在模式.var str = "1a1b1c";var reg = new RegExp("1.", "");alert(reg.test(str)); // true exec exec 查找并返回当前的匹配结果,并以数组的形式返回.var str = "1a1b1c";var reg = new R

  • 精通JS正则表达式(推荐)

    正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证 •替换文本.可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字 •根据模式匹配从字符串中提取一个子字符串.可以用来在文本或输入字段中查找特定文字 正则表达式语法 一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式.该模式描述在查找文字主体时待匹配的一个或多个字符串

  • 理解javascript正则表达式

    了解RegExp类型: ECMAScript通过RegExp类型来支持正则表达式. var expression=/pattern/flags; 正则表达式的模式(pattern)部分: 可以是任何简单或复杂的正则表达式,可以包含字符类,限定符,分组,向前查找,反向引用. 关于正则表达式中各种特殊字符(如 \,^,$,\w,\b 等)的含义可以参考 MDN 正则表达式-特殊字符 的整理.这里我们简单介绍一下向前查找和反向引用. 向前查找:正则表达式向前使用一些字符而不移动这些字符的位置,分为正向

  • 深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点

    具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以帮助你写出更好的,更易于理解和维护的代码,这些代码在几个月或是几年之后再回过头看看也是会觉得很自豪的. 书写可维护的代码(Writing Maintainable Code ) 软件bug的修复是昂贵的,并且

  • javascript正则表达式中分组详解

    之前写了一篇关于正则新手入门的文章,本以为对正则表达式相对比较了解 但是今天我又遇到了一个坑,可能是自己不够细心的原因吧,今天就着重和大家分享一下javascript正则表达式中的分组.如果你对JS正则表达式不够理解 可以点击这里了解更多. 分组在正则中用的还是比较广的,我所理解的分组 就是一对括号() ,每一对括号 就代表了一个分组, 分组可以分为: 捕获性分组 非捕获性分组 捕获性分组 捕获性分组会在 比如 match exec这样的函数中以第二项,第三项的形式得到相应分组的结果.先来看一个

  • javascript 正则表达式分组、断言详解

     javascript 正则表达式分组.断言详解 提示:阅读本文需要有一定的正则表达式基础. 正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下. 如果不用断言,以往用过的那些表达式,仅仅能获取到有规律的字符串,而不能获取无规律的字符串. 举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的.因

  • javascript正则表达式和字符串RegExp and String(二)

    在上篇文章给大家介绍了javascript正则表达式和字符串RegExp and String(一),本文给大家继续分享相关内容. 前言 我认为,在学习一门编程语言的过程中,字符串.数组.容器是非常重要的部分,为了提高编程效率,我通常会对字符串.数组以及容器作深入的学习,详细了解相关特点及对应的API.这篇文章是针对javascript字符串学习写下的笔记,在此与需要的朋友分享. 思维导图 字符串的创建方式 字符串是javascript中的基本类型之一,它对应的类型是String,可以通过两种方

  • javascript正则表达式和字符串RegExp and String(一)

    前言 正则表达式是javascript非常重要和常用的功能,在jquery等大型框架中用的非常频繁,最近抽时间学习了解了相关知识,记录下来与需要的朋友分享. 思维导图 RegExp(正则表达式)的创建方式 可以通过两种方式创建一个RegExp,具体如下: 通过/-./的方式来创建正则表达式(注意: /--/两边是没有单引号或双引号的) 通过RegExp构造方法来创建一正则表达式 为了更好的描述模式,正则表达式提供了3个标识,分别是: g/i/m g: 全局匹配:在整个字符串中匹配,而不是在第一次

  • 深入理解JS正则表达式---分组

    深入理解JS正则表达式---分组 之前写了一篇关于正则新手入门的文章,本以为对正则表达式相对比较了解 但是今天我又遇到了一个坑,可能是自己不够细心的原因吧,今天就着重和大家分享一下javascript正则表达式中的分组.如果你对JS正则表达式不够理解 可以点击这里了解更多. 分组在正则中用的还是比较广的,我所理解的分组 就是一对括号() ,每一对括号 就代表了一个分组,分组可以分为: •捕获性分组 •非捕获性分组 捕获性分组 捕获性分组会在 比如 match exec这样的函数中以第二项,第三项

  • 盘点javascript 正则表达式中 中括号的【坑】

    在javascript中使用正则时需要注意中括号里边的一个坑,那就是中括号内的元字符问题.自己踩到坑了,网上搜了一下还有不少人踩了这个坑,所以大概说一下. 中括号在正则中称为字符组(Character class),有的书翻译为字符类,还有的翻译成字符集.我觉得字符组更好点,毕竟class在计算机属于中代表面向对象里的"类".顾名思义,字符组为一组字符,它表示在一个位置里可能出现的多种字符.注意这里强调只匹配一个位置哦.(此段摘自-http://www.cnblogs.com/snan

  • JavaScript正则表达式的贪婪匹配和非贪婪匹配

    所谓贪婪匹配就是匹配重复字符是尽可能多的匹配,比如: "aaaaa".match(/a+/); //["aaaaa", index: 0, input: "aaaaa"] 非贪婪匹配就是尽可能少的匹配,用法就是在量词后面加上一个"?",比如: "aaaaa".match(/a+?/); //["a", index: 0, input: "aaaaa"] 但是非贪婪匹配

  • javascript正则表达式学习之位置匹配

    一.前言 正则表达式是匹配模式,要么是匹配字符,要么匹配位置. 其实在开发中很少用到匹配位置,本篇文章主要包含: 二.什么是位置 位置:相邻字符之间的位置. 三.如何匹配位置 在ES5中,共有6个锚:^, $, \b, \B, (?=p), (?!p) 可视化形式: RegExp:/^$\b\B(?=a)(?!b)/g 3.1 ^和$ ^(脱字符)匹配开头,在多行匹配中匹配行开头. $(美元符)匹配结尾,在多行匹配中匹配行结尾. 比如:我们把字符串的开头和结尾用#替换(位置可以替换成字符的):

随机推荐