【JavaScript】正则表达式--非贪婪模式截取任意字符串的笔记


文章目录
  1. 1. 场景
  2. 2. 正则表达式一
  3. 3. 正则表达式二
  4. 4. 排查问题
  5. 5. 正则表达式三
  6. 6. 结论

场景

要将下面的字符串截取两个{title:***,url:***}来。

 
       
1
2
3
4
5
 
       
<script>
{title: 'RegExp 对象参考手册',url: 'http://sodino.com/regexp.asp'},
{title: 'w3cSchool script', url: 'http://www.w3cSchool.com'},
{}
</script>

正则表达式一

 
       
1
2
3
4
5
6
7
8
9
10
 
       
var string = '<script>'
+ "{title:'RegExp 对象参考手册',url:'http://sodino.com/regexp.asp'},"
+ "{title:'w3cSchool script', url:'http://www.w3cSchool.com'},"
+ "{}"
+ '</script>';
var reg = / \{ . +\}/g; // 正则表达式
var result = string . match(reg);
console . log(result);

这个毫无疑问是全匹配,即输出为第一个{到最后一个}之间的全部内容:

 
       
1
2
 
       
D: \github \niVoVin>node test.js
[ ' {title: \'RegExp 对象参考手册 \',url: \'http://sodino.com/regexp.asp \' }, {title: \'w3cSchool script \', url: \'http://www.w3cSchool.com \' }, { }' ]

正则表达式二

书上说在表达式的后面加上?就是非贪婪模式了。即n?匹配包含零个或一个n的字符串。
那么目前想的是只匹配一个},那么将表达式修改为如下:

 
       
1
 
       
var reg = /\{.+\}?/g;

运行一下代码,发现输出是竟然是第一个{到字符串结尾:

 
       
1
2
 
       
D: \github \niVoVin>node test.js
[ ' {title: \'RegExp 对象参考手册 \',url: \'http://sodino.com/regexp.asp \' }, {title: \'w3cSchool script \', url: \'http://www.w3cSchool.com \' }, { }</script>' ]

?的作用竟然是忽略}吗?
陷入了深深的疑惑……


排查问题

当表达式一和表达式二对比时,直觉告诉你是由于引入?才导致的错误。
那么需要来验证下。

 
       
1
 
       
var reg = /script>?/g;

更换表达式,验证是否?一样会忽略掉>???
执行输出得到:

 
       
1
2
 
       
D:\github\niVoV in>node test.js
[ 'script>', 'script', 'script>' ]

所以?并不是忽略的作用。所以直觉不对。

再看表达式二的输出结果,结果是将第一个{后的内容全部输出,那就是说表达式二的结果是由于一直在匹配.+(任意数量的任意字符,除了换行和结束符),而没有匹配到截止符}?的原因。
而由于}?处于可匹配可不匹配的情况,解释器优先选择不匹配,导致截止符}是无效的。
参考链接正则基础之——贪婪与非贪婪模式

那么解决办法就变为截止符}不可设置为非贪婪,这样才有截止作用,而对应的是对.+(任意字符)执行非贪婪匹配,尽可能少的匹配{}之间的内容。


正则表达式三

 
       
1
 
       
var reg = /\{.+?\}/g;

输出结果:

 
       
1
2
3
 
       
D: \github \niVoVin>node test.js
[ ' {title: \'RegExp 对象参考手册 \',url: \'http://sodino.com/regexp.asp \' }',
' {title: \'w3cSchool script \', url: \'http://www.w3cSchool.com \' }' ]

很圆满。

由于.++表示最少出现一次.,所以第三行的空{}并没有被匹配成功。

结论

在表达式三中,.+表达任意字符串,}是截止符。
当使用n+ n* n?截取任意字符串时,如果待截取内容包括任意字符串,则非贪婪模式应尽可能少的匹配任中间的任意字符串,而非尽可能少的匹配截止符。


About Sodino

猜你喜欢

转载自blog.csdn.net/sodino/article/details/51685792
今日推荐