正则表达式学习笔记

正则表达式学习笔记

一篇记录了学习正则表达式的笔记。

1. 转义字符

在 HTMl 中转义字符以 & 符号开头,分号;结尾。比如小于号(<)就可以写 &lt; 或者 &#60,空格可以写成 &nbsp;;

在 JavaScript 中转义字符一般以反斜杠\开头,比如回车(也叫行结束符\r)、换行(\n)、水平制表符(\t)、垂直制表符(\v)、换页符(\f)。反斜杠则以两个 \ 符号表示(即\\)。

// 转义双引号 
var str = "abcde\"fg";       

// 反斜杠
var str2 = "abcd\\efg"; 

// 换行符
var str2 = "abcd\nefg";     

// 回车换行符
var str3 = "abcd\r\nefg";   

// 水平制表符,相当于键盘上的 Tab 键 (\b 想当于键盘上的退格键)
var str4 = "abcd\tefg";      

2. 两种创建正则的方法

有两种创建正则表达式的方式,一种是直接量(字面量)语法,一种是通过内置的对象 RegExp。

2.1 直接量语法

/pattern/attributes

比如匹配字符串 abc

var reg = /abc/, str = "abcde";

console.log(reg.test(str)); 
// true

检查字符串 str 中是否存在 abc

2.2 通过内置对象 RegExp

语法

new RegExp(pattern, attributes);

同样是匹配字符串 abc

var reg = new RegExp("abc"), str = "abcde";

console.log(reg.test(str)); 
// true

参数 pattern 的值可以是已有的正则表达式,但是如果在创建的时候不加关键字 new,返回的将是已有正则表达式的引用,而不是新创建的 RegExp 对象。

通过下面的两个例子理解上一句话

  1. 使用 new 创建正则表达式:

    var reg = new RegExp("abc"), str = "abcde";
    
    var newReg = new RegExp(reg); 
    newReg.myAttr = "123";
    
    console.log(newReg.myAttr); 
    // "123"
    console.log(reg.myAttr);    
    // undefined
    
  2. 不使用 new 创建正则表达式:

    var reg = new RegExp("abc"), str = "abcde";
    
    var newReg = RegExp(reg); 
    newReg.myAttr = "123";
    
    console.log(newReg.myAttr); 
    // "123"
    console.log(reg.myAttr);    
    // "123"
    

2.3 参数

参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。

参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。

简单的说 pattern 就是我们写的规则,而 attributes 是规则的修饰符。

修饰符 g,即 global,是否执行全局匹配

var reg = new RegExp("abc","g"), str = "abcdefgabc";

console.log(str.match(reg));   
// ["abc", "abc"]

// 查看正则表达式是否全局匹配
console.log(reg.global);      
// true 

使用全局匹配修饰符,匹配到两个 "abc"。可以通过 reg.global 去判断当前的正则表达式是否为全局匹配。

修饰符 i,即 ignoreCase,是否忽略大小写

var reg = new RegExp("abc","i"), str = "ABCDEFG";

console.log(str.match(reg));     
// ["ABC", index: 0, input: "ABCDEFG", groups: undefined]

// 查看正则表达式是否忽略大小写
console.log(reg.ignoreCase);    
// true  

使用忽略大小写修饰符,匹配到 "abc"。可以通过 reg.ignoreCase 去判断当前的正则表达式是否忽略大小写。

修饰符 m,即 multiline,是否以多行模式执行模式匹配

var reg = new RegExp("abc","gm"), str = "abcdefghjk\nabcde";

console.log(str.match(reg));     
// ["abc","abc"]

// 查看正则表达式是否以多行模式执行模式匹配
console.log(reg.multiline);    
// true   

使用多行匹配修饰符,匹配到两个 "abc"。可以通过 reg.multiline 去判断当前的正则表达式是否以多行模式执行模式匹配。

注意:所有的字符串如果不手动添加转义字符 \n 都为一行。

3. 字符组

在正则表达式中,字符组(一对方括号) [] 代表一位字符串的匹配范围

例如,匹配字符串中三位连续的数字:

var reg = /[1234567890][1234567890][1234567890]/g, str = "12345asda7890";

console.log(str.match(reg)); 
// ["123", "789"]

当匹配到符合的字符串片段后,就从当前位置继续向后匹配,不会回头再去匹配。

匹配所有的数字可简写为 [0-9],即 ASCII 码中数字 0 到 9 范围内的所有内容。

匹配所有的字母可简写 [A-z],所有的大写字母可简写 [A-Z],所有的小写字母可简写 [a-z]

4. 元字符

在正则表达式中,元字符(Metacharacter)是拥有特殊含义的字符。

4.1 元字符 .

元字符 .,用于查找单个字符,除了换行 \n 和行结束符 \r

var str = "That's hot!", patt1 = /h.t/g;

console.log(str.match(patt1));  
// "hat", "hot"

4.2 元字符 \w

元字符 \w,用于查找单词字符(world),相当于 [0-9A-z_]

var str = "Give 100%!", patt1 = /\w/g;

console.log(str.match(patt1));   
// ["G", "i", "v", "e", "1", "0", "0"]

元字符 \W,用于查找非单词字符,相当于 [^\w]

4.3 元字符 \d

元字符 \d,用于查找数字,即 [0-9]

var str = "Give 100%!", patt1 = /\d/g;

console.log(str.match(patt1));   
// [ "1", "0", "0"]

元字符 \D,用于查找非数字字符,相当于 [^\D]

4.4 元字符 \s

元字符 \s,用于查找空白字符,即 [\r\n\t\v\f ]

空白字符可以是:

  • 空格符 (space character)
  • 制表符 \t (tab character)
  • 回车符 \r (carriage return character)
  • 换行符 \n (new line character)
  • 垂直换行符 \v (vertical tab character)
  • 换页符 \f (form feed character)
var str = "Is this all\nthere is?", patt1 = /\s/g;

console.log(str.match(patt1));   
// [" ", " ", "↵", " "]

元字符 \S,用于查找非空白字符,相当于 [^\s]

4.5 元字符 \b

元字符 \b,用于匹配单词边界

var str = "Is this all\nthere is?", patt1 = /\bt/g;

console.log(str.match(patt1));  
 // ["t", "t"]

元字符 \B,用于查找非单词边界,相当于 [^\b]

var str = "Is this all\nthere is?", patt1 = /(\bthis\b|\bt\B)/g;

console.log(str.match(patt1));   
// ["this", "t"]

4.6 元字符 \xxx

\xxx 元字符用于查找以八进制数 xxx 规定的字符

对字符串中的八进制 127 (W) 进行全局搜索:

var str = "Hello World or word!", patt1 = /\127/g;

console.log(str.match(patt1));   
// ["W"]

忽略大小写呢?

var str = "Hello World or word!", patt1 = /\127/gi;

console.log(str.match(patt1));   
// ["W", "W"]

4.7 元字符 \xdd

\xdd 元字符查找以十六进制数 dd 规定的字符

对字符串中的十六进制 57 (W) 进行全局搜索:

var str = "Hello World or word!", patt1 = /\x57/g;

console.log(str.match(patt1));   
// ["W"]

4.8 元字符 \uxxxx

\uxxxx 元字符用于查找以十六进制数 xxxx 规定的 Unicode 字符

对字符串中的十六进制 0057 (W) 进行全局搜索:

var str = "Hello World or word!", patt1 = /\u0057/g;

console.log(str.match(patt1));   
// ["W"]

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

 "\u54c8\u55bd" // 哈喽

5. 量词(限定符)

量词,也叫限定符,用于描述前面字符(分组)可以出现的次数。

注意:在此节中,变量 n 可以代表任何字符。

5.1 量词 n+

量词 n+,匹配变量 n 至少出现 1 次。

var str = "Hello World or word!", patt1 = /o+/g;

console.log(str.match(patt1));   
// ["o", "o", "o", "o"]

5.2 量词 n*

量词 n*,匹配变量 n 出现 0 次到无数次(至少出现 0 次)。

var str = "or oo", patt1 = /o*/g;

console.log(str.match(patt1));  
 // ["o", "", "", "oo", ""]   "oo" -> 贪婪匹配

5.3 量词 n?

量词 n?,匹配变量 n 出现 0 次或 1 次。

var str = "or oo", patt1 = /o?/g;

console.log(str.match(patt1));   
// ["o", "", "", "o", "o", ""]

5.4 量词 n{X}

量词 n{X},匹配变量 n 出现 X 次。

var str = "or oo ooo", patt1 = /o{2}/g;

console.log(str.match(patt1));   
// ["oo", "oo"]

5.5 量词 n{X,Y}

量词 n{X,Y},匹配变量 n 出现 X 次到 Y 次。

var str = "or oo ooo", patt1 = /o{2,3}/g;

console.log(str.match(patt1));   
// ["oo", "ooo"]

5.6 量词 n{X,}

量词 n{X,},匹配变量 n 至少出现 X 次。

var str = "or oo ooo", patt1 = /o{1,}/g;

console.log(str.match(patt1));   
// ["o", "oo", "ooo"]

5.7 量词 ^n

量词 ^n,匹配任何开头为 n 的字符串。

var str = "abc def", str2 = "db cefc", patt1 = /^d/g;

console.log(str.match(patt1));   
// null
console.log(str2.match(patt1));  
// ["d"]

字符串 "abc def"a 开头。

5.8 量词 n$

量词 n$,匹配任何结尾为 n 的字符串。

var str = "abc def", str2 = "ab defc", patt1 = /c$/g;

console.log(str.match(patt1));   
// null
console.log(str2.match(patt1));  
// ["c"]

量次 ^$ 同时出现,字符串只能是中间的内容

var str = "abcdabcd", str2 = "abcd", patt1 = /^abcd$/g;

console.log(str.match(patt1));   
// null
console.log(str2.match(patt1));  
// ["abcd"]

5.9 量词 ?=n

量词 ?=n,匹配任何其后紧接指定字符串 n 的字符串。

例如,对其后紧跟 "all" 的 "is" 进行全局搜索:

var str="Is this all there is";
var patt1=/is(?= all)/g;

console.log(str.match(patt1));   
// ["is"]

量词 ?=n,也称为正向预查(正向断言)。

5.10 量词 ?!n

量词 ?!n,匹配任何其后没有紧接指定字符串 n 的字符串。

对其后没有紧跟 "all" 的 "is" 进行全局搜索:

var str="Is this all there is";
var patt1=/is(?! all)/gi;

console.log(str.match(patt1));  
// ["Is", "is"]

量词 ?!n,也有称为非正向预查(非正向断言)。

6. 分组与反向引用

限制单个字符的出现次数,直接在后面加上量词即可。但是如果我们要同时限制多个字符呢?我们可以通过括号 () 把需要一起限制的字符括在一起,再在括号的后面加上量词。

var str = "aa1bba123bcda123123bbbba123123123b3w";
var reg = /a(123){1,3}b/g; 

console.log(str.match(reg)); 
// ["a123b", "a123123b", "a123123123b"]

用括号 () 把多个字符包裹起来,这个行为称之为分组,被括号包裹起来的字符被称为子表达式

例如,/(abc)\d/g匹配所有 abc 后面紧跟一位数字的字符片段。

分组可以用来提取字符:

var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/;
var str = "2019-1-9", str2 = "2019-1-19", str3 = "2018-11-19";

console.log(str.match(reg));
// ["2019-1-9", "2019", "1", "9", index: 0, input: "2019-1-9", groups: undefined]
console.log(str2.match(reg));
// ["2019-1-19", "2019", "1", "19", index: 0, input: "2019-1-19", groups: undefined]
console.log(str3.match(reg));
// ["2018-11-19", "2018", "11", "19", index: 0, input: "2018-11-19", groups: undefined]

6.1 可捕获的分组

我们直接通过括号 () 进行的分组默认就是可捕获的。

通过反向引用可以引用前面子表达式匹配的内容。反向引用以反斜杠 \ 开头,后面紧跟数字 123456789... ,数字为几就代表引用第几个子表达式的值。

例如,\1 匹配第一个子表达式中匹配的内容:

var str = "aa asd dd";
var reg = /(\w)\1/g; 

console.log(str.match(reg)); 
// ["aa", "dd"]

子表达式的值可以重复引用:

var str = "aaaa";
var reg = /(\w)\1\1\1/g; 

console.log(str.match(reg)); 
// ["aaaa"]

如果引用的是不存在的分组:

var str = "aaaa\3", str2 = "aabb\3";
var reg = /(\w)\1(\w)\2\3/g; 

console.log(str.match(reg));   
// ["aaaa�"]
console.log(str2.match(reg));  
// ["aabb�"]

当引用了不存在的子表达式时,匹配反向引用的字符本身。例如, \3就配 \3

可捕获的分组也可以替换字符:

var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/;
var str = "2019-1-9", str2 = "2019-1-19", str3 = "2018-11-19";

console.log(str.replace(reg,'$1/$2/$3'));
// 2019/1/9
console.log(str2.replace(reg,'$1/$2/$3'));
// 2019/1/19
console.log(str3.replace(reg,'$1/$2/$3'));
// 2018/11/19

6.2 不可捕获的分组

我们知道默认的分组是可捕获的。但是所有的分组都可以捕获在某些情况下是不需要的。

可以使用非捕获括号 (?:n) 达到我们的目的,n 为我们自己的子表达式。

var str = "aa1bba123bcda123123bbbba123123123b3w";
var reg = /a(?:123){1,3}b/g; 

console.log(str.match(reg)); 
// ["a123b", "a123123b", "a123123123b"]

可捕获的分组捕获的内容会被存储在内存中,不可捕获的分组则不会捕获文本,也不会将它匹配到的内容单独分组来放到内存中。

所以,如果我们使用的分组不用捕获应该使用不可捕获的分组,更节省内存。

7. 或 与 非

7.1 或(分支) |

在正则表达式中,管道符 | (分支)的意思,只要满足一个分子就可匹配成功。

管道符 | 可用于子表达式 () 中:

var reg = /(123|456|789)[A-z]/g, str = "123bb45ccc";

console.log(str.match(reg)); 
// ["123b"]

也可用于表达式(方括号) [] 中:

var reg = /[123|456|789][A-z]/g, str = "1aa4Ab5Cc6E";

console.log(str.match(reg)); 
// ["1a", "4A", "5C", "6E"]

甚至就写在正则中。例如,检查一个字符串的首尾是否存在数字:

var reg = /^\d|\d$/g, str = "1ab";

console.log(reg.test(str)); 
// true

7.2 非 ^

符号 ^ 在正则表达式不同的位置拥有不同的含义:

  • /^abc/ - 在正则表达式的 头部 表示匹配以 abc 开头的字符串(符号 $ 匹配字符串的结束)。
  • /[^abc]/ - 放在正则表达式的 字符组 中则表示匹配除了 abc 以外的所有字符(非)。

放在正则表达式头部:

var reg = /^abc/g, str = "abcdefg", str2 = "123abcdefg";

console.log(str.match(reg));   
// ["abc"]
console.log(str2.match(reg));   
// null

第二行的头部也是可以匹配到的:

var reg = /^abc/gm, str = "123abcdefg\nabcs";

console.log(str.match(reg)); 
// ["abc"]

符号 ^ 放在表达式中意思为 ,即匹配除了这些以外的所有字符

var reg = /[^abc]/g, str = "abcdefg";

console.log(str.match(reg)); 
// ["d", "e", "f", "g"]

8. 没想好写啥

9. 贪婪匹配与非贪婪匹配

量词 默认使用的就是贪婪匹配,它会尽可能多的去匹配符合规则的字符串。

var str = "aaaaaaaaa", reg = /a+/g;

console.log(str.match(reg)); 
// ["aaaaaaaaa"]

贪婪匹配转换为非贪婪匹配,在量词后加上符号 ? 即可

var str = "aaaaaaaaa", reg = /a+?/g;

console.log(str.match(reg)); 
// ["a", "a", "a", "a", "a", "a", "a", "a", "a"]
var str = "11222333", reg = /\d{2,3}?/g;

console.log(str.match(reg)); 
// ["11", "22", "23", "33"]
var str = "11222333", reg = /\d??/g;

console.log(str.match(reg)); 
// ["", "", "", "", "", "", "", "", ""]

量词 n? ,表示匹配出现 0 次或者 1 次,再加上一个符号 ? 转换为非贪婪匹配,那么匹配的就是 0 次。

10. RegExp 对象属性

global 属性用于判断某个正则表达式是否具有修饰符 g

ignoreCase 属性用于判断某个正则表达式是否具有修饰符 i

multiline 属性用于判断某个正则表达式是否具有修饰符 m

lastIndex 属性标示下一次匹配的字符位置。常与 exec() 方法一起出现。

source 属性用于返回模式匹配所用的文本。

一个例子加深理解:

var str = "www.abc.com\n123.ab.cn";
var reg = /\w\./gm;

console.log(reg.lastIndex);  // 0
console.log(str.match(reg)); // ["w.", "c.", "3.", "b."]
console.log(reg.global);     // true
console.log(reg.ignoreCase); // false
console.log(reg.multiline);  // true
console.log(reg.source);     // "\w\."

reg.lastIndex = 4;
console.log(reg.lastIndex);  // 4
console.log(str.match(reg)); // ["w.", "c.", "3.", "b."]

reg.lastIndex = 4;
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // ["c.", index: 6, input: "www.abc.com↵123.ab.cn", groups: undefined]
console.log(reg.lastIndex); // 8
console.log(reg.exec(str)); // ["3.", index: 14, input: "www.abc.com↵123.ab.cn", groups: undefined]
console.log(reg.lastIndex); // 16
console.log(reg.exec(str)); // ["b.", index: 17, input: "www.abc.com↵123.ab.cn", groups: undefined]
console.log(reg.lastIndex); // 19
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0

exec() 当匹配到符合规则的字符时便会停下,等待下一次调用,直到字符串匹配结束。

11. RegExp 对象方法

11.1 test() 方法

test() 方法用于检测一个字符串是否匹配某个模式.

语法

RegExpObject.test(string)

如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false。

比如,检索 "www"

var str = "www.abc.com";
var patt1 = /www/;

console.log(patt1.test(str));   
// true

11.2 exec() 方法

exec() 方法用于检索字符串中的正则表达式的匹配。

语法

RegExpObject.exec(string)

如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。

在上一次匹配的基础上接着匹配。

var reg = /ab/g;
var str = "abababab";

console.log(reg.lastIndex); // 0 -> 当前开始匹配的索引位置
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 2
console.log(reg.exec(str)); // ["ab", index: 2, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // ["ab", index: 4, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 6
console.log(reg.exec(str)); // ["ab", index: 6, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 8
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]

exec() 当匹配到符合规则的字符时便会停下,等待下一次调用,直到字符串匹配结束。

reg.lastIndex 是可读写的。

var reg = /ab/g;
var str = "abababab";

console.log(reg.lastIndex); // 0 -> 当前开始匹配的索引位置
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]
reg.lastIndex = 0;       
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]

注意:如果不加修饰符 g,永远从索引 0 开始匹配。

11.3 exec() 方法与子表达式 ()

还是上面那个例子,但是使用 exec() 方法去匹配

var str = "aaaa", str2 = "aabb";
var reg = /(\w)\1(\w)\2/g; 

console.log(reg.exec(str2));   
// ["aabb", "a", "b", index: 0, input: "aabb", groups: undefined]

此类数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。

index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。

11.4 compile() 方法

compile() 方法用于在脚本执行过程中编译正则表达式。

compile() 方法也可用于改变和重新编译正则表达式。

该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。

语法

RegExpObject.compile(regexp,modifier)
  • 参数 regexp 为正则表达式。

  • 参数 modifier 为修饰符。

不推荐compile方法。你可以使用 RegExp 构造函数来得到相同效果。

12. 字符串上使用正则表达式

12.1 字符串的 match() 方法

同样的例子使用 match() 方法:

var str = "aabb";
var reg = /(\w)\1(\w)\2/g; 

console.log(str.match(reg));   
// ["aabb"]

如果不加全局修饰符 g 呢:

var str = "aabb";
var reg = /(\w)\1(\w)\2/; 

console.log(str.match(reg));   
// ["aabb", "a", "b", index: 0, input: "aabb", groups: undefined]

加了全局修饰符后结果与使用 exec() 方法类似。

12.2 字符串的 search() 方法

search() 方法返回匹配到字符串的位置。

var str = "123aabb";
var reg = /(\w)\1(\w)\2/; 

console.log(str.search(reg));  
// 3

如果匹配不到则返回 -1

var str = "123abcd";
var reg = /(\w)\1(\w)\2/; 

console.log(str.search(reg));   
// -1

12.3 字符串的 split() 方法

split() 方法以特定的规则去拆分字符串:

var str = "ab0c2de2f4gh5d";
var reg = /\d/g; 

console.log(str.split(reg));   
// ["ab", "c", "de", "f", "gh", "d"]

以数字为界限去拆分字符串

12.4 字符串的 replace() 方法

replace() 方法以特定的规则去替换字符串:

var str = "what is you name?";

console.log(str.replace("a","b"));   
// "whbt is you name?"

把第一个 "a" 替换为 "b"

注意,replace() 方法第一个参数不是正则表达式时,无法访问全局。

使用正则表达式:

var reg = /a/g; 
var str = "what is you name?";

console.log(str.replace(reg,"b"));   
// "whbt is you nbme?"

把所有的 "a" 替换为 "b"

replace() 方法可引用子表达式匹配到的值,例如,如何把形如 XXYY 的字符串变成 YYXX。

var reg = /(\w)\1(\w)\2/g; 
var str = "aabb 123 1122";

console.log(str.replace(reg,"$2$2$1$1"));   
// "bbaa 123 2211"

replace() 方法的第二个参数可以通过 $1 去引用第一个子表达式匹配到的值。 同理 $2 为第二个。

把某个字符替换为 $:

// 在 `replace()` 方法中,符号 `$` 有转义的意思,若想把某个字符替换为 `$`,最好写为 `$$`:
var reg = /(\w)\1/g; 
var str = "aabb 123 1122";

console.log(str.replace(reg,"$"));   // "$$ 123 $$"
console.log(str.replace(reg,"$$"));  // "$$ 123 $$"
console.log(str.replace(reg,"$1"));  // "ab 123 12"

replace() 方法可传入回掉函数:

var reg = /(\w)\1(\w)\2/g; 
var str = "aabb 123 1122";

console.log(str.replace(reg, function(val, $1, $2){
    // val 为全局结果   $1 为第一个子表达式匹配到的值   $2 ...
    return $2 + $2 + $1 + $1
}));   // "bbaa 123 2211"

13. 实例

实例 1,the-first-name 转为 theFirstName

var reg = /-(\w)?/g; 
var str = "the-first-name";

console.log(str.replace(reg, function(val, $1){
    return $1 ? $1.toUpperCase() : ""
}));   // "theFirstName"

反向转换:

var reg = /([A-Z])/g; 
var str = "theFirstName";

console.log(str.replace(reg, function(val, $1){
    return "-" + $1.toLowerCase()
}));  // the-first-name

实例 2,字符串简单去重 aaabbcccdd -> abcd

// 反向引用多个
var reg = /(\w)\1+/g; 
var str = "aaabbcccadd";

console.log(str.replace(reg, "$1"));   
// "abcd"

实例 3,格式化数字 100000000 -> 100.000.000

var reg = /\B(?=(\d{3})+(?!\d))/g; 
var str = "100000000000000";

console.log(str.replace(reg, "."));   
// "100.000.000.000.000"
var reg = /\B(?=(\d{3})+$)/g; 
var str = "100000000000000";

console.log(str.replace(reg, "."));   
// "100.000.000.000.000"
var reg = /(?=\B(\d{3})+$)/g; 
var str = "10000000000000000";

console.log(str.replace(reg, "."));   
// "10.000.000.000.000.000"

实例 4,匹配成对的 HTML 标签

var reg = /<([^>]+)>[\w\W]*<\/\1>/g; 
var str = "<div><h1>asdasd</h1></div>", str2 = "<p>asdasd</p>", str3 = "<div>asdasd</p>";

console.log(str.match(reg));
// "<div><h1>asdasd</h1></div>"
console.log(str2.match(reg));   
// ["<p>asdasd</p>"]
console.log(str3.match(reg)); 
// null

标签中不包含标签:

var reg = /<([^>]+)>[^<>]*<\/\1>/g; 
var str = "<div><h1>asdasd</h1></div>", str2 = "<p>asdasd</p>", str3 = "<div>asdasd</p>";

console.log(str.match(reg));
// "<h1>asdasd</h1>"
console.log(str2.match(reg));   
// ["<p>asdasd</p>"]
console.log(str3.match(reg)); 
// null

14. 学习资料

w3school 的 RegExp 对象

MDN web docs

《JavaScript 正则表达式迷你书》

渡一教育-正则表达式

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

推荐阅读更多精彩内容

  • 原文参考自: https://www.jianshu.com/p/681d3e07fb0f 一、原理概论 1、正则...
    Rui哥阅读 553评论 0 2
  • 自从年前得空写了两篇文章之后就开始忙了,这一忙就是2个月😭。当时信誓旦旦说的定期写篇博客的计划也就泡汤了🤣,不过好...
    景科同学阅读 1,153评论 0 9
  • 一.正则表达式匹配原则 占有字符和零宽度 在正则表达式匹配过程中,如果子表达式匹配到的是字符内容,并被保存在结果之...
    Coree阅读 529评论 0 0
  • [TOC] 什么是正则表达式? 正则表达式是一组由字母和符号组成的特殊文本, 它可以用来从文本中找出满足你想要的格...
    Selen_Lin阅读 561评论 0 0
  • 正则表达式练习题点击这里 创建一个正则表达式 使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示: ...
    打铁大师阅读 1,244评论 0 6