正则表达式

1. 示例

字面量 var reg = /\bis\b/                                           匹配全局中两边为边界的 is 的单词
构造函数 var reg = new RegExp('\bis\b', 'g')          效果同上


2. 修饰符

g: global                                                                   全文搜索,如果不添加则搜索到第一个匹配的停止
i: ignore case                                                           忽略大小写,默认大小写敏感
m: multiple lines                                                      多行搜索


3. 元字符

\t                                                                                水平制表符
\v                                                                               垂直制表符
\n                                                                               换行符
\r                                                                                回车符
\o                                                                               空字符
\f                                                                                换页符
\cx                                                                             与 X 对应的控制字符(Ctrl+X)


4. 字符类

用 [ ] 来构建简单的类
      [abc]                                                                   即匹配这一类字符,abc 其中的任何一个
      [^]                                                                       字符类取反
      [^abc]                                                                 把 abc 以外的字符匹配

例:
var b = 'a1b2c3d4'
b.replace(/[abc]/g, 'X')                                            // 'X1X2X3d4'
b.replace(/[^abc]/g, 'X')                                          // 'aXbXcXXX'


5. 范围类

      [a-z]                                                                     小写的 a 到 z 的 26 个字母
      [A-Z]                                                                    大写的 A 到 Z 的 26 个字母
      [0-9]                                                                     0 到 9 的 10 个数字
      [0-9-]                                                                    0 到 9 的 10 个数字外加 '-'

例:
      'a1b2c3X4'.replace(/[a-z]/g, 'Q')                         // 'Q1Q2Q3X4'
      'a1b2c3X4'.replace(/[A-Z]/g, 'Q')                        // 'a1b2c3Q4'
      'a1b2c3X4'.replace(/[a-zA-Z]/g, 'Q')                   // 'Q1Q2Q3X4'
      'a1b2c3X4'.replace(/[0-9]/g, 'Q')                         // 'aQbQcQXQ'
      'a-b-c-11'.replace(/[0-9-]/g, 'Q')                           // 'aQbQcQQQ'


6. 预定义类

.                          [^\r\n]                                              除了回车符合换行符之外的所有字符
\d                        [0-9]                                                数字字符
\D                        [^0-9]                                             非数字字符
\s                        [\t\n\xOB\f\r]                                   空白符
\S                       [^\t\n\xOB\f\r]                                 非空白符
\w                       [a-zA-Z_0-9]                                    单词字符(字母,数字下划线)
\W                       [^a-zA-Z_0-9]                                 非单词字符


7. 边界

^                                                                                  以 xxx 开始
$                                                                                  以 xxx 结束
\b                                                                                 单词边界
\B                                                                                非单词边界


8. 量词

?                                                                                 出现零次或一次(最多出现一次)
+                                                                                  出现一次或多次(至少出现一次)
\                                                                                    出现零次或多次(任意次数)
{n}                                                                                出现 n 次
{n, m}                                                                           出现 n 到 m 次
{n, }                                                                              至少出现 n 次


9. 贪婪模式与非贪婪模式

贪婪模式(默认)                                                              尽可能多的匹配
非贪婪模式(在量词后加上?)                                          尽可能少的匹配

例:
      '12345678'.replace(/\d{3,6}/g, 'X')                          // 'X78'
      '12345678'.replace(/\d{3,6}?/g, 'X')                        // 'XX78'


10. 分组、或

使用 () 可以达到分组的功能,使量词作用于分组
使用 | 来表达或

例:
      'a1b2c3d4'.replace(/([a-z]\d){3}/g, 'X')                                 // 'Xd4'
      'ByronsperBryCasper'.replace(/Byr(ca|on)sper/g, 'X')      // 'XX'


11. 反向引用

'2016-11-25'.replace(/(\d{4})-(\d{2})-(\d{2})/g, '$2$3$1')            // '11/25/2016'


12. 非捕获性分组

在分组中的前面加上 ?: 代表非捕获性分组

例:

var str = 'abcabc'                                        var str = 'abcabc'
var re = /(abc){2}/                                       var re = /(?:abc){2}/
re.test(str)                                              re.test(str)
console.log(RegExp.$1)                                    console.log(RegExp.$1)
// abc                                                    // (空白)


13. 前瞻

正向前瞻                                exp(?=assert)
负向前瞻                                exp(?!assert)
正向后顾                                exp(?<=assert)                      JavaScript 不支持
负向后顾                                exp(?<=assert)                      JavaScript 不支持

例:
'a2*34v8'.replace(/\w(?=\d)/g, 'X')                                       // 'X2*X3X8'
'a2*34v8'.replace(/\w(?!\d)/g, 'X')                                        // 'aX*3XvX'


14. 对象属性(正则表达式书写时便设置,之后不能再更改)

global                                                     是否全文搜索,默认 false
ignore case                                            是否大小写敏感,默认 false
multiline                                                 多行搜索,默认false
lastIndex                                                是当前表达式匹配内容的最后一个字符的下一个位置
source                                                    正则表达式的文本字符串

例:
var reg1 = /\w/                                                    非全局匹配时 lastIndex 为 0
var reg2 = /\w/gim
reg1.global              // false                                  reg2.global               // true
reg1.ignoreCase     // false                                  reg2.ignoreCase      //true
reg1.multiline          // false                                  reg2.multiline           // true
reg1.lastIndex          // 0                                        reg2.lastIndex          // 0
reg1.source              // \w                                      reg2.source              // \w


15. RegExp.prototype.test(str)

用于测试字符串参数中是否存在匹配正则表达式模式的字符串,如果存在则返回 false
var reg1 = /\w/                 reg1.test('a')                  // true
var reg2 = /\w/g               reg1.test('$')                  // false

reg2.test('ab')                                                   // true
reg2.test('ab')                                                   // true
reg2.test('ab')                                                   // false

因为全局匹配时 lastIndex 会循环重置


16. RegExp.prototype.exec(str)

使用正则表达式模式对字符串执行搜索,并将更新全局 RegExp 对象的属性以反映匹配结果

如果没有匹配的文本则返回 null,否则返回一个结果数组
     1. index                                             声明匹配文本的第一个字符的位置
     2. input                                              存放被检索的字符串 string


17. 非全局调用

调用非全局的 RegExp 对象的 exec() 时,返回数组
第一个元素是与正则表达式相匹配的文本
第二个元素是与 RegExpObject 的第一个子表达式想匹配的文本(如果有的话)
第三个元素是与 RegExp 对象的第二个子表达式相匹配的文本(如果有的话),一次类推

var reg3 = /\d(\w)(\w)\d/
var ts = '$1a22bb3cy4dd5ee'
var ret = reg3.exec(ts)
console.log(reg3.lastIndex + '\t' + ret.index + '\t' + ret.toString())
// '0 1 1a22,a,z'

var reg4 = /\d(\w)(\w)/g
while (ret = reg4.exec(ts)) {
         console.log(reg4.lastIndex + '\t' + ret.index + '\t' + ret.toString())
}
// '5 1 1a22,a,2'
// '11 7 3cy4,c,y'


18. String1.prototype.search(reg)

search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串
方法返回第一个匹配结果 index,查找不到返回 -1
search() 方法不执行全局匹配,它将忽略标志 g,并且总是从字符串的开始进行检索

例:
'a1b2c3d1.search(//g)'                                               // 1
'a1b2c3d1.search(1)'                                                 // 1
'a1b2c3d1.search('10')'                                             // -1


19. String.prototype.match(reg)

match() 方法将检索字符串,以找到一个或多个与 regexp 匹配的文本
regexp 是否具有标志 g 对结果影响很大


20. 非全局调用

1. 如果 regexp 没有标志 g,那么 match() 方法就只能在字符串中执行一次匹配
2. 如果没有找到任何匹配的文本,将返回 null
3. 否则它将返回一个数组,其中存放了与它找到的匹配文本有关的信息
4. 返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本

除了常规的数组元素之外,返回的数组还含有 2 个对象属性:
      index 声明匹配文本的起始字符,在字符串的位置
      input 声明对 stringObject 的引用

var reg3 = /\d(\w)\d/
var reg4 = /\d(\w)\d/g
var ts = '$1a2b3c4d5e'
var ret = ts.match(reg3)
console.log(ret)                                                          // ['1a2', 'a']
console.log(ret.index + '\t' + reg3.lastIndex)                            // '1 0'


21. 全局调用

1. 如果 regexp 具有标志 g 则 match() 方法将执行全局检索,找到字符串的所有匹配子字符串
2. 没有找到任何匹配的子串,则返回 null
3. 如果找到了一个或多个匹配子串,则返回一个数组
4. 数组元素中存放的是字符串所有的匹配子串,而且也没有 index 属性或 input 属性

var ret = ts.match(reg4)
console.log(ret)                                                        // ['1a2', '3c4']
console.log(ret.index + '\t' + reg4.lastIndex)                          // 'undefined 0'


22. String.prototype.split(reg)

'a,b,c,d'.split(',')'                                               // ['a', 'b', 'c', 'd']
'a1b2c3d'.split(/\d/)                                          // ['a', 'b', 'c', 'd']


23. String.prototype.replace(reg)

1. String.prototype.replace(str, replaceStr)
2. String.prototype.replace(reg, replaceStr)
3. String.prototype.replace(reg, function)

'a1b1c1'.replace('1', 2)                                            // 'a2b1c1'
'a1b1c1'.replace(/1/g, 2)                                          // 'a2b2c2'


24. function 参数含义

function 会在每次匹配替换的时候调用,4 个参数如下:
      1. 匹配字符串                                                                              必填
      2. 正则表达式分组内容,没有分组则没有该参数                        可选
      3. 匹配项在字符串中的 index                                                     必填
      4. 原字符串                                                                                 必填

'a1b2c3d4e5'.replace(/\d/g, () => {
      console.log(index)
      return parseInt(match) + 1
})
// 1 => 3 => 5 => 7 => 9 => 'a2b3c4d5e6'

'a1b2c3d4e5'.replace(/(\d)(\w)(\d)/g, (match, group1, group2, group3, index, origin) => {
      console.log(match)                                  // '1b2'
      return group1 + group2                              // '3d4'
})                                                        // 'a12c4e5'
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • ** 题记:接上回,我们说到了关于正则表达式的基本的语法,这次我们就来继续拓展正则表达式的内容,包括了正则表达式中...
    帅帅哒小白阅读 999评论 0 6
  • 什么是正则表达式 Regular Expression使用单个字符串来描述,匹配一系列符合某个句法规则的字符串 说...
    打铁大师阅读 771评论 1 6
  • 正则表达式 正则表达式(Regular Expression)是计算机科学的一个概念。正则表达式使用单个字符串来描...
    yshenhn阅读 352评论 0 0
  • 基本简介 正则表达式(Regular Expression): 通过由普通字符和特殊字符组成的文字模板完成对字符串...
    流云012阅读 691评论 0 0
  • 自从年前得空写了两篇文章之后就开始忙了,这一忙就是2个月😭。当时信誓旦旦说的定期写篇博客的计划也就泡汤了🤣,不过好...
    景科同学阅读 1,150评论 0 9