JavaScript的正则表达式

正则表达式

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为”元字符”)。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
通过使用正则表达式,可以:

  1. 测试字符串内的模式。
    例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
  2. 替换文本。
    可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
  3. 基于模式匹配从字符串中提取子字符串。
    可以查找文档内或输入域内特定的文本。

目前,正则表达式已经在很多软件中得到广泛的应用,包括 *nix(Linux, Unix等)、HP 等操作系统,PHP、C#、Java 等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。

特殊字符(称为”元字符”)

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为”元字符”)组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

而往往正则的使用,那些元字符才是最为重要的部分,但是元字符真的不少,所以想要强记真的不容易,但是还是有一些使用场景较多的需要注意;

  1. 字符类别

    • \ 反斜杠
      将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’n’ 匹配一个换行符。序列 ‘\’ 匹配 “” 而 “(” 则匹配 “(“。
    • . 点号,
      匹配任意单个字符, 但是行结束符除外:n r u2028 或 u2029。
    • \d
      匹配任一阿拉伯数字,等价于[0-9]
    • \D
      匹配任意一个不是阿拉伯数字的字符。等价于1
    • \w
      匹配任意来自基本拉丁字母表中的字母数字字符,还包括下划线。等价于 [A-Za-z0-9_]。
    • \W
      匹配任意不是基本拉丁字母表中单词(字母数字下划线)字符的字符。等价于 2
    • \s
      匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格。 等价于 [ fnrtv​u00a0u1680​u180eu2000​u2001u2002​u2003u2004​ u2005u2006​u2007u2008​u2009u200a​u2028u2029​​u202fu205f​ u3000]。
    • [\b]
      匹配一个退格符(backspace)(不要与\b 边界匹配混淆)
    • \S
      匹配一个非空白符
    • \uhhhh
      匹配 Unicode 值为 hhhh (四个十六进制数字)的字符。
  2. 字符集合

    • [xyz]
      一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符’-‘指定一个范围。
    • [^xyz]
      一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 ‘-‘ 指定一个范围内的字符。
  3. 边界

    • ^
      匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处。
    • $
      匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处。
    • \b
      匹配一个零宽单词边界(zero-width word boundary),如一个字母与一个空格之间。 (不要和 [b] 混淆)
    • \B
      匹配一个零宽非单词边界(zero-width non-word boundary),如两个字母之间或两个空格之间。
  4. 分组(grouping)与反向引用(back references)

    • (x) 括号包括内容
      匹配 x 并且捕获匹配项。 这被称为捕获括号(capturing parentheses)。例如,/(foo)/ 匹配且捕获 “foo bar.” 中的 “foo”。被匹配的子字符串可以在结果数组的元素 [1], …, [n] 中找到,或在被定义的 RegExp 对象的属性 $1, …, $9 中找到。捕获组(Capturing groups)有性能惩罚。如果不需再次访问被匹配的子字符串,最好使用非捕获括号(non-capturing parentheses),见下面的(?:x)。
    • \n
      其中n 是一个正整数。一个反向引用(back reference),指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串。例如,/apple(,)sorange1/ 匹配 “apple, orange, cherry, peach.” 中的 “apple,orange,”。一个更全面的例子在该表格下面。
    • (?:x)
      匹配 x 不会捕获匹配项。这被称为非捕获括号(non-capturing parentheses)。匹配项不能够从结果数组的元素 [1], …, [n] 或已被定义的 RegExp 对象的属性 $1, …, $9 再次访问到。
  5. 数量词(Quantifiers)

    • x*
      匹配前面的模式 x 0 或多次。
    • x+
      匹配前面的模式 x 1 或多次。等价于 {1,}。
    • x*? x+?
      像上面的 * 和 + 一样匹配前面的模式 x,然而匹配是最小可能匹配。这是非贪婪匹配的写法,主要是在量词(* +)后面添加?来非贪婪匹配
    • x?
      匹配前面的模式 x 0 或 1 次。
    • x(?=y)
      只有当 x 后面紧跟着 y 时,才匹配 x【其中y是不算匹配结果的】。 例如,/Jack(?=Sprat)/ 只有在 ‘Jack’ 后面紧跟着 ‘Sprat’ 时,才会匹配它。/Jack(?=Sprat|Frost)/ 只有在 ‘Jack’ 后面紧跟着 ‘Sprat’ 或 ‘Frost’ 时,才会匹配它。然而,’Sprat’ 或 ‘Frost’ 都不是匹配结果的一部分。
    • x(?!y)
      只有当 x 后面不是紧跟着 y 时,才匹配 x。例如,/d+(?!.)/ 只有当一个数字后面没有紧跟着一个小数点时,才会匹配该数字。/\d+(?!\.)/.exec(“3.141”) 匹配 141 而不是 3.141。
    • x|y
      匹配 x 或 y
    • x{n}
    1. 是一个正整数。前面的模式 x 连续出现 n 次时匹配。
    • x{n,}
    1. 是一个正整数。前面的模式 x 连续出现至少 n 次时匹配。
    • x{n,m}
    1. 和 m 为正整数。前面的模式 x 连续出现至少 n 次,至多 m 次时匹配。
  6. 断言(Assertions)

    • x(?=y)
      仅匹配被y跟随的x。举个例子,/Jack(?=Sprat)/,如果”Jack”后面跟着sprat,则匹配之。/Jack(?=Sprat|Frost)/ ,如果”Jack”后面跟着”Sprat”或者”Frost”,则匹配之。但是,”Sprat” 和”Frost” 都不会在匹配结果中出现。
    • x(?!y)
      仅匹配不被y跟随的x。举个例子,/d+(?!.)/ 只会匹配不被点(.)跟随的数字。/\d+(?!\.)/.exec(‘3.141’) 匹配”141″,而不是”3.141″

javascript的正则表达式对象

正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、replace、search 和 split 方法。本章介绍 JavaScript正则表达式。

构建

var patt=new RegExp(pattern,modifiers);
或者更简单的方式:
var patt=/pattern/modifiers;
//pattern(模式) 描述了表达式的模式
//modifiers(修饰符) 用于指定全局匹配g、区分大小写i的匹配和多行匹配m、Unicode序列u、粘性匹配y

有两种方法来创建一个RegExp对象:一是字面量、二是构造函数。要指示字符串,字面量的参数不使用引号,而构造函数的参数使用引号
当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 ),下面两个等价

var re = new RegExp("\\w+");
var re = /\w+/;

属性

  1. RegExp.length 值为2
  2. RegExp.prototype.global
    是否开启全局匹配,也就是匹配目标字符串中所有可能的匹配项,而不是只进行第一次匹配。
  3. RegExp.prototype.ignoreCase
    在匹配字符串时是否要忽略字符的大小写。
  4. RegExp.prototype.lastIndex
    下次匹配开始的字符串索引位置。
  5. RegExp.prototype.multiline
    是否开启多行模式匹配(影响 ^ 和 $ 的行为)。
  6. RegExp.prototype.source
    正则对象的源模式文本。
  7. RegExp.prototype.sticky
    是否开启粘滞匹配。

方法

1. RegExp.prototype.exec(str)

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

当正则表达式使用 “g” 标志时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的 lastIndex 属性指定的位置开始。(test() 也会更新 lastIndex 属性)

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);
}

使用了g代表可以多次运行,运行exec返回的结果myArray[0]是匹配的全部字符串,myArray[1], …[n ] 匹配的是括号中的分组捕获,myArray是数组,但是还有index属性,匹配到的字符位于原始字符串的基于0的索引值 ;以及input属性,匹配的是原始字符串。
myRe.exec()每运行完了一次之后,myRe也会发生变化,主要是属性lastIndex的变化,下一次运行myRe.exec()都可以从这个更新的lastIndex处开始匹配;

注意:不要把正则表达式字面量(或者RegExp构造器)放在 while 条件表达式里。由于每次迭代时 lastIndex的属性都被重置,如果匹配,将会造成一个死循环。并且要确保使用了’g’标记来进行全局的匹配,否则同样会造成死循环。

如果你只是为了判断是否匹配(true或 false),可以使用 RegExp.test() 方法,或者 String.search() 方法。

2. RegExp.prototype.test(str)

测试当前正则是否能匹配目标字符串。test() 方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true 或 false。

/^cwj(god)+/.test('cwjgod');  //true

JavaScript中的string和正则结合使用

String的match、replace、search和split方法都可以使用正则表达式。

match方法

str.match(regexp);

参数:
一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。如果你未提供任何参数,直接使用 match() ,那么你会得到一个包含空字符串的 Array :[“”] 。
当参数是一个字符串或一个数字,它会使用new RegExp(obj)来隐式转换成一个 RegExp。如果它是一个有正号的正数,RegExp() 方法将忽略正号。
返回值:
一个包含了整个匹配结果以及任何括号捕获的匹配结果的 Array ;如果没有匹配项,则返回 null 。

如果正则表达式没有 g 标志,则 str.match() 会返回和 RegExp.exec() 相同的结果。而且返回的 Array 拥有一个额外的 input 属性,该属性包含被解析的原始字符串。另外,还拥有一个 index 属性,该属性表示匹配结果在原字符串中的索引(以0开始为整个匹配,1…n后面就是()括号里面的子匹配)。

replace方法

这是一个强大的方法,

str.replace(regexp|substr, newSubStr|function)

参数1:以下二选一

  • regexp (pattern)
    一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。
  • substr (pattern)
    一个要被 newSubStr 替换的字符串。其被视为一整个字符串,而不是一个正则表达式。仅仅是第一个匹配会被替换。

参数二:以下二选一

  • newSubStr (replacement)
    用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数。
  • function (replacement)
    一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数。

在第一个参数是字符串的时候,第二个字符串可以是字符串或者是函数:

  • 第二个参数是字符串
    会有以下几种特殊字符的存在,

    $$    代表插入一个 "$"。
    $&    代表插入匹配的子串。
    $`    代表插入当前匹配的子串左边的内容。
    $'    代表插入当前匹配的子串右边的内容。
  • 第二个参数是函数
    函数的返回值作为替换字符串,参数match是匹配的子字符串

在第一个参数是正则表达式的时候,第二个参数可以是字符串或者函数

  • 第二个参数是字符串

    $$    代表插入一个 "$"。
    $&    代表插入匹配的子串。
    $`    代表插入当前匹配的子串左边的内容。
    $'    代表插入当前匹配的子串右边的内容。
    $n    n 是个小于100的非负整数,那么$n就代表第 n 个括号匹配的字符串
  • 第二个参数是函数
    函数的返回值作为替换字符串,参数如下:

    1.参数match是匹配的子字符串
    2.参数【p1, p2,...】[$1, $2,...] 代表第n个括号匹配的字符串
    3.offset 匹配到的子字符串在原字符串中的偏移量
    4.string  被匹配的原字符串。

    这个参数顺序是固定的,不能跳着写,也就是说如果你需要offset,那么必须把第一个参数在的全部匹配match以及所有的()子匹配都列出来在参数中,才能正确的映射到所有参数上

search方法

str.search(regexp)
  • 参数
    一个正则表达式(regular expression)对象。如果传入一个非正则表达式对象,则会使用 new RegExp(obj) 隐式地将其转换为正则表达式对象。
  • 返回值
    如果匹配成功,则 search() 返回正则表达式在字符串中首次匹配项的索引。否则,返回 -1。

split方法

str.split([separator[, limit]])

split() 方法使用指定的分隔符字符串将一个String对象分割成字符串数组,以将字符串分隔为子字符串,以确定每个拆分的位置。
两个参数

  • separator
    指定表示每个拆分应发生的点的字符串。separator 可以是一个字符串或正则表达式。 如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。
  • limit
    一个整数,限定返回的分割片段数量。当提供此参数时,split 方法会在指定分隔符的每次出现时分割该字符串,但在限制条目已放入数组时停止。如果在达到指定限制之前达到字符串的末尾,它可能仍然包含少于限制的条目。新数组中不返回剩下的文本。
  1. 0-9
  2. A-Za-z0-9_
    原文作者:caoweiju
    原文地址: https://segmentfault.com/a/1190000011653521
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞