JavaScript正则表达式的模式匹配

时间:2022-04-08 05:34:41

今天刚学了关于JavaScript 正则表达式的模式匹配,下面总结了一些知识点和大家分享一下~(适合初学者)


1、正则表达式的定义

        JavaScript中的正则表达式用RegExp对象表示,可用RegExp()构造函数创建RegExp对象。正则表达式直接量定义为包含在一对斜杠(/)之间的字符。

var pattern = /s$/;  //匹配所有以字母“s”结尾的字符串
//等价于:
var pattern = new RegExp(“s$”);


1.1 直接量字符

    非字母的字符匹配,这些字符需通过反斜线(\)作为前缀进行转义。

正则表达式的直接量字符

  字符

  匹配

  字母和数字字符

自身

  \o

NUL字符(\u0000

  \t

制表符(\u0009

  \n

换行符(\u000A

  \v

垂直制表符(\u000B

  \f

换页符(\u000C

  \r

回车符(\u000D

  \xnn

由十六进制数nn指定的拉丁字符,例如:\x0A等价于\n

  \uxxxx

有十六进制数xxxx指定的Unicode字符,例如:\u0009等价于\t

  \cX

控制字符^X,例如:\cJ等价于换行符\n


    特殊标点符号:

        ^ $ . * + ? = ! : | \ / ( ) [ ] { }


1.2 字符类(character class

    将直接量字符单独放进方括号内组成了字符类:[直接量字符]

         "^"符号:定义否定字符类

例子:

/[abc]/  //和字母“a”、“b”、“c”中的任意一个匹配。
/[^abc]/  //匹配的是“a”、“b”、“c”之外的所有字符
/[a-z]/  //匹配拉丁字母表中的小写字母
/[a-zA-Z0-9]/  //匹配拉丁字母表中任何字母和数字
正则表达式的字符类
字符 匹配
  [...]

方括号内的任意字符

  [^...]

不在方括号内的任意字符

  .

除换行符和其他Unicode行终止符之外的任意字符

  \w

任何ASCII字符组成的单词,等价于[a-zA-Z0-9]

  \W

任何不是ASCII字符组成的单词,等价于[^a-zA-Z0-9]

  \s

任何Unicode空白符

  \S

任何非Unicode空白符的字符,注意\w\S不同

  \d

任何ASCII数字,等价于[0-9]

  \D

除了ASCII数字之外的任何字符,等价于[^0-9]

  [\b]

退格直接量(特例)

    \b:在字符类中,表示退格符。/[\b]/


1.3 重复

正则表达式的重复字符语法
字符 含义
  {n,m}

匹配前一项至少n次,但不能超过m

  {n,}

匹配前一项n次或者更多次

  {n}

匹配前一项n

  ?

匹配前一项0次或者1次,也就是说前一项是可选的,等价于{0,1}

  +

匹配前一项1次或者多次,等价于{1,}

  *

匹配前一项0次或者多次,等价于{0,}

例子:

/\d{2,4}/   //匹配2~4个数字
/\w{3}\d?/   //精确匹配三个单词和一个可选的数字
/\s+java\s+/   //匹配前后带有一个或者多个空格的字符串”java”
/[^(]*/   //匹配一个或多个非左括号的字符

    非贪婪的重复:在待匹配的字符后跟随一个问号,如:“??”、“+?”、“*?”或者“{1,5}?”。

例子:

    当使用“aaa”作为匹配字符串时,/a+/会匹配它的三个字符,/a+?/只能匹配第一个a


1.4 选择、分组和引用

 “|”:用于分割供选择的字符。

 “()”圆括号的作用:

    1、把单独的项组合成子表达式,以便可以像处理一个独立的单元那样用“ | ”、“ * ”、“ + ”或者“ ? ”等来对单元内的项进行处理。例如:

/java(script)?/     //可以匹配字符串“java”,其后可有“script”也可没有。
/(ab|cd)+|ef/    //可以匹配“ef”,也可以匹配“ab”或“cd”的一次或多次的重复。
    2、在完整的模式中定义子模式。如:

/[a-z]+(\d+)/     //可以从检索到的匹配中抽取数字。
    3、允许在同一正则表达式的后部引用前面的子表达式。通过在字符“ \”后加一位或多位数字来实现。这个数字指定了带圆括号的子表达式在正则表达式中的位置。注意:因为子表达式可以嵌套另一个子表达式,所以它的位置是参与计算的左括号的位置。如:

\1     //引用的是第一个带圆括号的子表达式。

    正则表达式中前一个子表达式的引用,指的是与那个模式相匹配的文本的引用。

    在正则表达式中不用创建带数字编码的引用,也可以对子表达式进行分组,以“(?:”和“)”来进行分组,这种改进的圆括号并不生成引用。

正则表达式的选择、分组和引用字符
字符 含义
   |

选择,匹配的是该符号左边的子表达式或右边的子表达式

   (...)  

组合,将几个项组合为一个单元,这个单元可通过*”、“+”、“?”和“|”等符号加以修饰,而且可以记住和这个组合相匹配的字符串以供此后的引用使用

   (?...) 

只组合,把项组合到一个单元,但不记忆与该组相匹配的字符

   \n   

和第n个分组第一次匹配的字符相匹配,组是圆括号中的子表达式(也有可能是嵌套的),组索引是从左到右的括号数,“(?:”形式的分组不编码


1.5 指定匹配的位置

    \b匹配一个单词的边界。像\b这样的元素不匹配某个可见的字符,它们指定匹配发生的合法位置。这些元素为正则表达式的锚,它们将模式定位在搜索字符串的特定位置上。

    任意正则表达式都可以作为锚点条件。

正则表达式中的锚字符
字符 含义
    ^   

匹配字符串的开头,在多行检索中,匹配一行的开头

    $   

匹配字符串的结尾,在多行检索中,匹配一行的结尾

    \b   

匹配一个单词的边界,简言之,就是位于单词\w\W中间的位置,或位于字符\w和字符串的开头或者结尾之间的位置

(注意:[\b]匹配的是退格符)

    \B   

匹配非单词边界的位置

 (?=p)

零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符

 (?!p) 

零宽负向先行断言,要求接下来的字符不与p匹配

例子:

/[Jj]ava([Ss]cript)?(?=\:)/ 
//可以匹配“JavaScript:The Definitive Guide”中的“JavaScript”,但不能匹配“Java in a Nutshell”中的“Java”,因为它后面没有冒号。


1.6 修饰符

正则表达式修饰符
字符 含义
   i 

执行不区分大小写的匹配

   g 

执行一个全局匹配,简言之,即找到所有的匹配,而不是在找到第一个之后就停止

   m 

多行匹配模式,^匹配一行的开头和字符串的开头,$匹配行的结束和字符串的结束



2、用于模式匹配的String方法

 String支持4中正则表达式的方法:

  1、search():参数是一个正则表达式,返回第一个与之匹配的子串的起始位置,如果找不到匹配的子串将返回-1

             如果参数不是正则表达式,会先通过RegExp构造函数将它转换成正则表达式,search()方法不支持全局检索。

"JavaScript".search(/script/i);  //返回值为4.
  2、replace():用以执行检索与替换操作。第一个参数是一个正则表达式,第二个参数是要进行替换的字符串。

例子:

//将所有不区分大小写的javascript都替换成大小写正确的JavaScript
text.replace(/javascript/gi,"JavaScript");

    如果在替换字符串中出现了$加数字,那么replace()将用与指定的子表达式相匹配的文本来替换这两个字符。

//一段引用文本起始于引号,结束于引号
//中间的内容区域不能包含引号
var quote = /"([^"]*)"/g;
//用中文半角引号替代英文引号,同时要保持引号之间的内容(存储在$1中)没有被修改
text.replace(quote,'"$1"');

    replace()方法的第二个参数可以是函数,该函数能够动态地计算替换字符串。

  3、match()方法:唯一参数是一个正则表达式(或通过 RegExp()构造函数将其转换为正则表达式),返回的是一个有匹配结果组成的数组。如歌正则表达式设置了修饰符 g,则该方法返回的数组包含字符串中的所有匹配结果。如:

"1 plus 2 equals 3",match(/\d+/g);  //返回["1","2","3"]

    如果正则表达式没有设置修饰符gmatch()就不会进行全局检索,只检索第一个匹配。

    如果match()返回一个数组a,那么a[0]存放的是完整的匹配,a[1]存放的则是与第一个圆括号括起来相匹配的子串,以此类推。为了和方法replace()保持一致,a[n]存放的是$n的内容。

    例子:使用如下的代码来解析一个URL:

var url = /(\w+):\/\/([\w.]+)\/(\S*)/;
var text = "Visit my blog at http://www.example.com/~david";
var result = text.match(url);
if(result != null){
    var fullurl = result[0];  //包含"http://www.example.com/~david"
    var protocol = result[1];  //包含"http"
    var host = result[2];  //包含"www.example.com"
    var path = result[3];  //包含"~david"
}
  4、s plit()方法

    String对象的最够一个和正则表达式相关的方法是split()

    Split():将字符串拆分为一个子串组成的数组,使用的分隔符是split()的参数。参数也可以是一个正则表达式。

"123,456,789".split(",");  //返回["123","456","789"]
"1, 2, 3, 4, 5".split(/\s*,\s*/);  //返回["1","2","3","4","5"]


3、RegExp对象

    RegExp()用以创建新的RegExp对象。第一个参数包含正则表达式的主体部分,第二个参数可选,第二个参数是指定正则表达式的修饰符,只能传入gim或它们的组合。

 注意:不论是字符串直接量还是正则表达式,都使用”\”字符作为转义字符的前缀。

如:

//全局匹配字符串中的5个数字,注意这里使用了"\\",而不是"\"
var zipcode = new RegExp("\\d{5}","g");

  如果待检索的字符串是由用户输入的,就必须使用RegExp()构造方法,在程序运行时创建正则表达式。


3.1、RegExp的属性

  每个RegExp对象都包含5个属性:

      source:只读,包含正则表达式的文本;

      global:只读的布尔值,说明正则表达式是否带修饰符g

      ignoreCase:只读的布尔值,说明正则表达式是否带修饰符i

      multiline:只读的布尔值,说明正则表达式是否带修饰符m

      lastIndex:可读/写的整数。