《正则表达式必知必会》读书笔记

注:本文写的是 JavaScript 中的正则表达式语法。在不同编程语言里,正则表达式的功能和语法往往会有明显的差异。

正则表达式有两种基本用途:搜索(匹配一些文本)和替换(匹配并替换一些文本)。绝大多数正则表达式引擎的默认行为是只返回第一个匹配结果。

元字符(metacharacter)

元字符大致有两种:一种是用来匹配文本的(比如 . ),另一种是用来定义正则表达式的语法的(比如 [ ] )。

匹配一个字符或字符集合

  • . :匹配除换行符( \n )以外的任何单个字符。
  • \ :对特殊字符进行转义。
  • [ ] :定义字符集合。
  • - :一个特殊的元字符,常用在字符集合里定义一个字符区间,在字符集合外,只是一个普通字符。
  • ^ :对字符集合进行取非匹配。

重复匹配

  • + :匹配一个或多个字符或字符集合( {1,}
  • * :匹配零个或多个字符或字符集合( {0,}
  • ? :匹配零个或一个字符或字符集合( {0,1}
  • { } :定义匹配的重复次数
    • {3} :匹配重复3次
    • {3,} :匹配至少重复3次
    • {2,4} :匹配最少重复2次,最多重复4次

特殊的元字符

同一个元字符的大写形式与它的小写形式在功能上往往刚好相反。

  • \d :匹配任何一个数字字符([0-9])
  • \D :匹配任何一个非数字字符([^0-9])
  • \w :[a-zA-Z0-9_]
  • \W :[^a-zA-Z0-9_]
  • \s :匹配任何一个空白字符
  • \S :匹配任何一个非空白字符

空格、制表符(Tab 键, \t )、换行符( \n )、回车符( \r )、换页符( \f )和垂直制表符( \v )称为 空白字符

  • \s :匹配一个空白字符,它是一个空白字符集合。
// \s 等价于下面的字符集合
\s == [\t\n\v\f\r\u0020\u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]

如果你单单需要匹配空格,请使用 空格的 Unicode 码( \u0020 进行匹配,不要直接使用空格字符进行匹配。

\r\n 是 Windows 系统使用的文本行结束标签,而 Linux/Unix 只使用 \n 来结束一个文本行。 参看: 回车和换行

防止过度匹配

* + {n,} 都是所谓的 贪婪型元字符 ,它们在匹配时的行为模式是多多益善而不是适可而止的。为了解决这种状况,只需在这几个元字符后面加上一个 ? 后缀即可将其变为 懒惰型元字符*? +? {n,}? )。

varstr ="This is <span>my</span> home <span>page</span>!";
vartest1 = str.match(/<span>.*<\/span>/g);
vartest2 = str.match(/<span>.*?<\/span>/g);
console.log(test1);// ["<span>my</span> home <span>page</span>"]
console.log(test2);// ["<span>my</span>", "<span>page</span>"]

位置匹配

单词边界

  • \b :匹配一个单词的开始或结尾(这里的单词是一个由 \w 匹配的字符中的一个或多个字符组成的字符串)

    \b :只匹配一个位置,不匹配任何字符

    \b 匹配这样的一个位置,这个位置位于一个能够用来构成单词的字符(字母、数字和下划线,即 \w 匹配的字符)和一个不能用来构成单词的字符(即 \W 匹配的字符)之间。

difference between \w and \b regular expression meta characters

  • \B :匹配一个非单词边界的位置

字符串边界

  • ^ :匹配整个字符串的开始位置
  • $ :匹配整个字符串的结束位置

子表达式(subexpression)

子表达式用来对表达式进行分组和归类。

  • ( ) :定义一个子表达式

  • (x) :匹配并记住 x,括号被称为捕获括号

  • (?:x) :匹配但不记住 x,括号为非捕获括号
varstr ="__abc_abcabc";
vartest1 = str.match(/abc{2,}/g);
vartest2 = str.match(/(abc){2,}/g);
console.log(test1);// null
console.log(test2);// ["abcabc"]

回溯引用:前后一致匹配(backreference)

回溯引用是子表达式的另一种重要的用途。

  • \1 :对应着第一个子表达式
  • \2 :对应着第二个子表达式
  • ……以此类推

注意:在执行替换操作时,引用子表达式的语法不再是 \1 ,而是 $1

varstr ="begin <h1>Right title</h1> ... <h1>Wrong title</h2> end";
vartest1 = str.match(/<h[1-6]>.*?<\/h[1-6]>/g);
vartest2 = str.match(/<h([1-6])>.*?<\/h\1>/g);
console.log(test1);// ["<h1>Right title</h1>", "<h1>Wrong title</h2>"]
console.log(test2);// ["<h1>Right title</h1>"]

前后查找(lookaround)

前后查找:对某一位置的前、后内容进行查找。

JavaScript 不支持向后查找,只支持向前查找。

  • 向前查找(用 ?= 定义)指定了一个必须匹配但不在结果中返回的模式。

  • x(?=y) :匹配 x 当且仅当 x 后面跟着 y。

varstr ="http://www.baidu.com";
vartest1 = str.match(/.+(:)/g);
vartest2 = str.match(/.+(?=:)/g);
console.log(test1);// ["http:"]
console.log(test2);// ["http"]

其他语法

  • x|y :匹配 x 或 y,x、y可以是一个字符或子表达式
  • [\b] :匹配一个退格(不要和 \b 搞混了)
  • \uhhhh :匹配一个与相应的 Unicode 编码对应的字符

在 JavaScript 中使用正则表达式

RegExp 对象

// 定义一个正则表达式
varreg1 =/pattern/flags;
varreg2 =newRegExp(pattern [, flags]);
// pattern 为正则表达式
// flags:
// g 全局匹配
// i 不区分大小写匹配
// m 多行匹配

如果使用m标志,^和$匹配的开始或结束输入字符串中的每一行,而不是整个字符串的开始或结束。

  • RegExp.prototype.exec(str): 为指定的一段字符串执行搜索匹配操作,返回一个数组或者 null
  • RegExp.prototype.test(str): 用来查看正则表达式与指定的字符串是否匹配,返回 true 或 false

String 对象

// 交换字符串中的两个单词
varre =/(\w+)\s(\w+)/;
varstr ="John Smith";
varnewstr = str.replace(re,"$2, $1");
console.log(newstr);// Smith, John
// 交换字符串中的两个单词
varre =/\s/;
varstr ="a bc \n dd";
varnewstr = str.split(re);
console.log(newstr);// ["a", "bc", "", "", "dd"]

以上。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章