js正则表达式迷你书(笔记)

一、字符匹配攻略

  • 横向模糊匹配(贪婪模式)
  • 纵向模糊匹配 [ ]
  • 字符组 [ ] : 匹配一个字符
  • 范围表示法:比如 [123456abcdefGHIJKLM],可以写成 [1-6a-fG-M]。用连字符 - 来省略和简写
  • 排除字符组 :例如 [^abc],表示是一个除 "a"、"b"、"c"之外的任意一个字 符。字符组的第一位放 ^(脱字符),表示求反的概念。
  • 常见的简写形式
字符组 具体含义
\d          表示 [0-9]。表示是一位数字。 记忆方式:其英文是 digit(数字)。
\D 表示 [^0-9]。表示除数字外的任意字符。本
\w 表示 [0-9a-zA-Z_]。表示数字、大小写字母和下划线。 记忆方式:w 是 word 的简写,也称单词字符。
\W 表示 [^0-9a-zA-Z_]。非单词字符。
\s 表示 [ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s 是 space 的首字母,空白符的单词是 white space
\S 表示 [^ \t\v\n\r\f]。 非空白符。
. 表示 [^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符 除外。记忆方式:想想省略号 ... 中的每个点,都可以理解成占位符,表示任何类似的东西。
  • 常见的量词简写模式
量词 具体含义
{m,}    表示至少出现 m 次。
{m} 等价于 {m,m},表示出现 m 次。
? 等价于 {0,1},表示出现或者不出现。 记忆方式:问号的意思表示,有吗?
+ 等价于 {1,},表示出现至少一次。 记忆方式:加号是追加的意思,得先有一个,然后才考虑追加。
* 等价于 {0,},表示出现任意次,有可能不出现。 记忆方式:看看天上的星星,可能一颗没有,可能零散有几颗,可能数也数不过来。
  • 贪婪匹配与惰性匹配

通过在量词后面加个问号就能实现惰性匹配

惰性量词 贪婪量词
{m,n}? {m,n}
{m,}? {m,}
?? ?
+? +
*? *

TIP : 对惰性匹配的记忆方式是:量词后面加个问号,问一问你知足了吗,你很贪婪吗?

  • 多选分支 : (p1|p2|p3),其中 p1、p2 和 p3 是子模式,用 |(管道符)分隔,表示其中任何之一

  • 案列分析

// 匹配时间
var regex = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/; 
console.log( regex.test("23:59") );
console.log( regex.test("02:07") );
console.log( regex.test("7:9") );
  // => true
  // => true
  // => true
// 匹配id
var regex = /id=".*?"/ // 一定要加惰性匹配,不然就是贪婪匹配,结果会错误的
var string = '<div id="container" class="main"></div>'; console.log(string.match(regex)[0]);
// => id="container"

或者如下

// 匹配id
var regex = /id="[^"]*"/  // 先匹配id="  然后匹配任何不是"的任意个字符 最后再匹配" 
var string = '<div id="container" class="main"></div>'; console.log(string.match(regex)[0]);
// => id="container"

二、位置匹配攻略

  • 关于位置的6个锚
含义
^ (脱字符)匹配开头,在多行匹配中匹配行开头
$ (美元符号)匹配结尾,在多行匹配中匹配行结尾
\b 单词边界,具体就是 \w 与 \W 之间的位置,也包括 \w 与 ^ 之间的位置,和 \w 与 $ 之间的位置
\B \b 的反面的意思,非单词边界
(?=p) 正向断言(预查) ;检查某个字符后面的字符是否满足某个规则,该规则不成为匹配结果,并且不成为捕获组
(?!p) 负向断言(预查); 检查某个字符后面的字符是否不满足某个规则,该规则不成为匹配结果,并且不成为捕获组
  • 案列分析
// 数字的千位分隔符表示法
var regex = /(?!^)(?=(\d{3})+$)/g;
var result = "12345678".replace(regex, ',') console.log(result);
// => "12,345,678"
result = "123456789".replace(regex, ','); console.log(result);
// => "123,456,789"

三、正则表达式括号的作用

  • 分组: var regex = /(ab)+/g; 其中括号是提供分组功能,使量词 + 作用于 "ab" 这个整体
  • 分支结构: 而在多选分支结构 (p1|p2) 中,此处括号的作用也是不言而喻的,提供了分支表达式的所有可能
  • 提取数据:可以从数组中获取,也可以从构造函数饿全局属性1至9来获取
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
console.log( string.match(regex) );
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]

match 返回的一个数组,第一个元素是整体匹配结果,然后是各个分组(括号里)匹配的 NOTE 内容,然后是匹配下标,最后是输入的文本
另外也可以使用正则实例对象的 exec 方法

  • 替换
// 比如,想把 yyyy-mm-dd 格式,替换成 mm/dd/yyyy
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1"); console.log(result);
// => "06/12/2017"
  • 反向引用 :\捕获组编号
// 写一个正则支持匹配如下三种格式
// 2016-06-12
// 2016/06/12
// 2016.06.12
var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/; var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true 
console.log( regex.test(string2) ); // true 
console.log( regex.test(string3) ); // true 
console.log( regex.test(string4) ); // false
  • 分组后面有量词: 分组后面有量词的话,分组最终捕获到的数据是最后一次的匹配
// 分组 (\d) 捕获的数据是 "5"
 var regex = /(\d)+/;
var string = "12345";
console.log( string.match(regex) );
// => ["12345", "5", index: 0, input: "12345"]
var regex = /(\d)+ \1/;
console.log( regex.test("12345 1") ); // => false
console.log( regex.test("12345 5") ); // => true
  • 非捕获符号: (?:)只想要括号最原始的功能, 不会成为捕获组
  • 案例分析
// 字符串 trim 方法模拟
function trim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
console.log( trim(" foobar ") ); // => "foobar"
// 字符串 trim 方法模拟
function trim (str) {
return str.replace(/^\s*(.*?)\s*$/g, "$1");
}
console.log( trim(" foobar ") );
// => "foobar"
// 这里使用了惰性匹配 *?,不然也会匹配最后一个空格之前的所有空格的
// 非捕获组
// 将每个单词的首字母转换为大写
function titleize (str) {
return str.toLowerCase().replace(/(?:^|\s)\w/g, function (c) {
return c.toUpperCase(); });
}
console.log( titleize('my name is epeli') ); 
// => "My Name Is Epeli"

四、回溯法

简单总结就是,正因为有多种可能,所以要一个一个试。直到,要么到某一步时,整体匹配成功了;要么最后都试完后,发现整体匹配不成功。
贪婪量词“试”的策略是:买衣服砍价。价钱太高了,便宜点,不行,再便宜点。
惰性量词“试”的策略是:卖东西加价。给少了,再多给点行不,还有点少啊,再给点。
分支结构“试”的策略是:货比三家。这家不行,换一家吧,还不行,再换。

五、正则表达式的拆分

结构 说明
字面量          匹配一个具体字符,包括不用转义的和需要转义的。比如 a 匹配字符 "a", 又比如 \n 匹配换行符,又比如 . 匹配小数点。
字符组 匹配一个字符,可以是多种可能之一,比如 [0-9],表示匹配一个数字。也有 \d 的简写形式。 另外还有反义字符组,表示可以是除了特定字符之外任何一个字符,比如 [^0-9], 表示一个非数字字符,也有 \D 的简写形式。
量词     表示一个字符连续出现,比如 a{1,3} 表示 "a" 字符连续出现1到 3 次。 另外还有常见的简写形式,比如 a+ 表示 "a" 字符连续出现至少一次。
匹配一个位置,而不是字符。比如 ^ 匹配字符串的开头,又比如 \b 匹配单词边界, 又比如 (?=\d) 表示数字前面的位置。
分组 用括号表示一个整体,比如 (ab)+,表示 "ab" 两个字符连续出现多次, 也可以使用非捕获分组 (?:ab)+。
分支 多个子表达式多选一,比如 abc|bcd,表达式匹配 "abc" 或者 "bcd" 字符子串。 反向引用,比如 \2,表示引用第 2 个分组。
  • 操作符
操作符描述 操作符 优先级
转义符 \ 1
括号和方括号 (...)、(?:...)、(?=...)、(?!...)、[...] 2
量词限定符 {m}、{m,n}、{m,}、?、*、+ 3
位置和序列 ^、$、\元字符、一般字符 4
管道符(竖杠) 5
  • 所有结构里,用到的元字符总结如下:

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

六、replace 是很强大的

总体来说 replace 有两种使用形式,这是因为它的第二个参数,可以是字符串,也可以是函数。 当第二个参数是字符串时,如下的字符有特殊的含义:

属性 描述
1,2,...,$99 匹配第 1-99 个 分组里捕获的文本
$& 匹配到的子串文本
$` 匹配到的子串的左边文本
$' 匹配到的子串的右边文本
$$ 美元符号
  • 案例分析
// 把 "2,3,5",变成 "5=2+3"
var result = "2,3,5".replace(/(\d+),(\d+),(\d+)/, "$3=$1+$2"); 
console.log(result);
// => "5=2+3"
// 把 "2,3,5",变成 "222,333,555"
var result = "2,3,5".replace(/(\d+)/g, "$&$&$&"); 
console.log(result);
// => "222,333,555"
// 把 "2+3=5",变成 "2+3=2+3=5=5"
var result = "2+3=5".replace(/=/, "$&$`$&$'$&");
 console.log(result);
// => "2+3=2+3=5=5"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容