正则贪婪与惰性之理解,达人指点!

kaizi_sun 2009-09-17 05:36:01
abcabc92123abc

/abc/g        匹配 abc
/(abc)*/g 匹配 abcabc 贪婪
/.*abc/g 匹配 abcabc92123abc 贪婪
/.*?abc/g 匹配 abc, 92123abc 惰性
/.*(abc)*/g 匹配 abcabc92123abc 贪婪
/.*?(abc)*/g 匹配 abcabc 前惰性后贪婪
/.*?(abc)*?/g 匹配 abc 92123abc 都惰性


请教我的理解对吗? 请帮忙指出错误,谢谢大家。因为自己真的有点浑!
谢谢
...全文
475 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
kaizi_sun 2009-09-21
  • 打赏
  • 举报
回复
d
aimie 2009-09-20
  • 打赏
  • 举报
回复
如17楼的
例:a89a777asaaa
/a.*?a/懒惰,匹配a89a
/a.*a/贪婪,匹配整个字符串.
kaizi_sun 2009-09-20
  • 打赏
  • 举报
回复
谢谢大家的理解,其实我对这个原理是知道的.但是出来的结果,我都有点模糊了.为什么5楼和 9楼运行出来的结果不一样啊?
不解了? 还有,我的答案里哪几个理解是错呢?
mbh0210 2009-09-19
  • 打赏
  • 举报
回复
贪婪是一直匹配完字符串
懒惰是遇到就停止
kaizi_sun 2009-09-18
  • 打赏
  • 举报
回复
还有理解么,大家讨论下!
kaizi_sun 2009-09-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 s_liangchao1s 的回复:]
HTML code<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head></head><body><spanid="¡­
[/Quote]

Thanks
s_liangchao1s 2009-09-18
  • 打赏
  • 举报
回复

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<span id="ospan"></span>
<script>
str="abcabc92123abc"
arr=[/abc/g,/(abc)*/g,/.*abc/g,/.*?abc/g,/.*(abc)*/g,/.*?(abc)*/g,/.*?(abc)*?/g];
for(i=0;i<arr.length;i++){
document.getElementById("ospan").innerHTML +="第"+i+"项结果: " + str.match(arr[i])[0] + "<br/>";
}
/*
第0项结果: abc
第1项结果: abcabc
第2项结果: abcabc92123abc
第3项结果: abc
第4项结果: abcabc92123abc
第5项结果: abcabc
第6项结果:
*/
</script>
<!--
/abc/g
没什么说的 正则顺序从左到右 a b c
/(abc)*/g
*(0--尽可能多) 第一次匹配(abc)由于有*修饰是贪婪的 所以会选择继续匹配abc 结果 abc abc
/.*abc/g
.*贪婪 尽可能匹配任意多的字符. 所以第一次会匹配到最后一个字符.然后由于后面紧接abc
所以正则引擎会导致回溯把倒数第一个字符让出来匹配abc.由于最后一个字符是c不能匹配a
所以引擎会继续回溯.知道回溯到倒数第三个字符可以匹配abc了.所以结果为abcabc92123abc
/.*?abc/g
.*?惰性的 尽可能少的匹配字符.所以一开始.*?选择不匹配.然后紧接abc去从开头匹配.正好abc可以匹配
引擎就报告匹配成功 所以结果是abc
/.*(abc)*/g
这个跟第三项基本差不多 .*匹配到字符末尾紧接abc回溯 直到倒数第三个 匹配宣布成功 结果就是整个字符串
/.*?(abc)*/g
这个跟第四项差不多 .*?贪婪选择不匹配 然后(abc)*尽可能多的匹配 所以两次abc遇到9宣告失败
/.*?(abc)*?/g
都是惰性 所以都选择不匹配

我这解析的挺片面.楼主想要完全理解就要系统的去学习下
其实你这个正则如果有^ $锚点控制情况又不一样了
回溯也是正则最重要的一点 楼主可以去了解下
-->
</body>
</html>

  • 打赏
  • 举报
回复
a.*? 将匹配满足条件最短的字符串 a=====b

更正为

a.*?b 将匹配满足条件最短的字符串 a=====b
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 s_liangchao1s 的回复:]
引用 13 楼 li1229363 的回复:
简单点,一个从前面向后匹配,一个从后面向前匹配。

实际上复杂些。大体上可以这样理解吧?

JS对正则的支持上稍微弱了点。

晕 我第一次听说正则还有从后向前匹配这一说...
[/Quote]

他所说的应该是贪婪量词,是先吃尽所有字符,然后再一个一个地吐出来,直接匹配成功为止
而懒惰量词,是从头开始一个字符一个字符地吃,直接匹配成功为止

我想其意思应该是贫婪是逐渐向前匹配,而懒惰是向后慢慢匹配吧

贪婪和懒惰的匹配过程是这样的:

懒惰是从左边一个一个地吃直到匹配为止,不加 ? 的是一口吃掉整个字符串,然后从最后一个一个地吐出来直到匹配为止

字符串
a=====b=====b===

a.*b 将匹配满足条件最长的字符串 a=====b=====b

工作方式:
首先将:a=====b=====b=== 全部吃掉,从右边一个一个地吐出来

1. a=====b=====b=== 不匹配,吐出一字符
2. a=====b=====b== 不匹配,再吐出一字符
3. a=====b=====b= 不匹配,再吐出一字符
4. a=====b=====b 匹配了,结束。如果再不匹配继续吐,直到没有字符了,匹配失败

a.*? 将匹配满足条件最短的字符串 a=====b

工作方式:
从左边一个一个地吃掉字符
1. a 不能匹配表达式,继续吃
2. a= 不能匹配表达式,继续吃
3. a== 不能匹配表达式,继续吃
4. a=== 不能匹配表达式,继续吃
5. a==== 不能匹配表达式,继续吃
6. a===== 不能匹配表达式,继续吃
7. a=====b 呵呵,终于能匹配表达式了,匹配结束,匹配位置留于字符 b 后面,继续其他的匹配。如果不能匹配则一个一个地吃掉整个字符串直到吃完为止若还没有匹配则匹配失败。
kaizi_sun 2009-09-18
  • 打赏
  • 举报
回复

/abc/g 匹配 abc 运行结果 abc
/(abc)*/g 匹配 abcabc 运行结果 abcabc abc
/.*abc/g 匹配 abcabc92123abc 运行结果 abcabc92123abc
/.*?abc/g 匹配 abc, 92123abc 运行结果 abc
/.*(abc)*/g 匹配 abcabc92123abc 运行结果 abcabc92123abc
/.*?(abc)*/g 匹配 abcabc 运行结果 abcabc abc
/.*?(abc)*?/g 匹配 abc 92123abc 运行结果 ,

真是迷糊了,最后一个竟然出来串逗号
达人能具体点评下么? 真的要弄清楚哦

kaizi_sun 2009-09-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xinyung 的回复:]
在你写了个g之后结果可能跟你预想的不一样了,
最好的方法是整个串匹配,加上开始结束:/^$/,这样就比较容易看出惰性和贪婪
[/Quote]
加个g不就代表全局匹配么? 这个全局匹配是不是这个意思: 没有g匹配到一个就停,而有g则剩下的继续匹配?
kaizi_sun 2009-09-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 renzaijiang 的回复:]
ls的又在想当然了
运行一下才是真理
JScript code<script>
str="abcabc92123abc"
arr=[/abc/g,/(abc)*/g,/.*abc/g,/.*?abc/g,/.*(abc)*/g,/.*?(abc)*/g,/.*?(abc)*?/g];for(i=0;i<arr.length;i++)
alert(arr[i].exec(str));</script>
[/Quote]

哎~~我也是想当然了,菜啊!貌似错好一些。我把匹配结果发出来一会,大家帮忙分析分析
s_liangchao1s 2009-09-18
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 li1229363 的回复:]
简单点,一个从前面向后匹配,一个从后面向前匹配。

实际上复杂些。大体上可以这样理解吧?

JS对正则的支持上稍微弱了点。
[/Quote]
晕 我第一次听说正则还有从后向前匹配这一说...
li1229363 2009-09-18
  • 打赏
  • 举报
回复
简单点,一个从前面向后匹配,一个从后面向前匹配。

实际上复杂些。大体上可以这样理解吧?

JS对正则的支持上稍微弱了点。
xsir317 2009-09-18
  • 打赏
  • 举报
回复
惰性就是遍历字符串的时候,每前进一个字符串都试图匹配结束。
贪婪就是一次吃进所有能匹配的,然后再试图匹配后面的,如果后面不能匹配再回溯。

你可以用RegexBuddy之类的工具,对正则匹配进行Debug。这样看得非常清楚。
renzaijiang 2009-09-17
  • 打赏
  • 举报
回复
ls的又在想当然了
运行一下才是真理

<script>
str="abcabc92123abc"
arr=[/abc/g,/(abc)*/g,/.*abc/g,/.*?abc/g,/.*(abc)*/g,/.*?(abc)*/g,/.*?(abc)*?/g];
for(i=0;i<arr.length;i++)
alert(arr[i].exec(str));
</script>
boringame 2009-09-17
  • 打赏
  • 举报
回复
匹配都对。。。
li1229363 2009-09-17
  • 打赏
  • 举报
回复
恩。楼上的说得对。

但是贪婪的和一般的却别在事后的时候,需要慎重,不然影响了正则的执行力奥率,却功能并没有得到提升
xinyung 2009-09-17
  • 打赏
  • 举报
回复
在你写了个g之后结果可能跟你预想的不一样了,
最好的方法是整个串匹配,加上开始结束:/^$/,这样就比较容易看出惰性和贪婪
kaizi_sun 2009-09-17
  • 打赏
  • 举报
回复
对的话跟我说下,估计会有错

87,926

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧