欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

用"/(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是"d"?

程序员文章站 2022-05-19 08:46:09
...
而用"/a(.*?)/"正则表达式匹配"abcd"则只得到"a"

以及另一个问题:
用"/a(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是无法匹配?

PHP代码:
用"/(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是"d"?用"/(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是"d"?用"/(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是"d"?关于"?"元字符
用"/(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是"d"?/*知乎首问*/

回复内容:

对于“ "/(.*?)d/"正则表达式匹配"abcd"为什么得到的是"abcd"而不是"d"?”这个问题还在嚷嚷非贪婪匹配的我只能叹一声你们这些战五渣。

首先你们说的正则匹配一般是指partial match,或叫search。js里应该就是exec,但是我没查过。这个策略是独立于正则表达式本身的。一旦用了这个策略,正则引擎将寻找起点最靠左的可行解。 非贪婪是满足条件即返回结果。

* 是零或任意多个,所以 a(.*?) 实际上是相当于:

a        * = 0
a.       * = 1
a..      * = 2
a...     * = 3
…        …
因为无论你的正则表达式怎么写,第一个字符在元字符串的位置出现的越早,这个答案的优先级就更高。 根本和贪婪非贪婪没关系好么!!@Tim Shen 巨巨已经说了!!
有个很重要的前提是正则表达式得成功啊,就是说要找到一个可行解!
/(.*?)d/
因为正则是从前往后逐字符扫描的

a yes
b yes
c yes
d bingo 第一个 a..d 对应过去就是abcd 两个点分别匹配到bc
第二个 a 后面的(.*?)看都不用看
第三个 ...d 对应过去就是abcd 三个点分别匹配到abc 因为这个匹配的实际效果是先找到第一个符合“.”的内容(就是随便什么都行),然后向后找到第一个“d”为止 其实跟贪婪不贪婪没什么区别,原因只是因为正则是从前往后匹配而不是从后往前匹配 正则表达式多用才是王道! 看到了一个非常棒的帖子,从NFA引擎机制上解释了这一问题
引用过来供大家参考
本题相关关键内容已加粗并下划线
(其中有两张图大家看完一定就明白了)


对于贪婪与非贪婪模式,可以从应用和原理两个角度进行理解,但如果想真正掌握,还是要从匹配原理来理解的。

先从应用的角度,回答一下“什么是贪婪与非贪婪模式?”

2.1 从应用角度分析贪婪与非贪婪模式
2.1.1 什么是贪婪与非贪婪模式
先看一个例子

举例:

源字符串:aa
test1
bb
test2
cc

正则表达式一:
.*


匹配结果一:
test1
bb
test2


正则表达式二:
.*?


匹配结果二:
test1
(这里指的是一次匹配结果,所以没包括
test2


根据上面的例子,从匹配行为上分析一下,什是贪婪与非贪婪模式。

正则表达式一采用的是贪婪模式,在匹配到第一个“
”时已经可以使整个表达式匹配成功,但是由于采用的是贪婪模式,所以仍然要向右尝试匹配,查看是否还有更长的可以成功匹配的子串,匹配到第二个“
”后,向右再没有可以成功匹配的子串,匹配结束,匹配结果为“
test1
bb
test2
”。当然,实际的匹配过程并不是这样的,后面的匹配原理会详细介绍。

仅从应用角度分析,可以这样认为,贪婪模式,就是在整个表达式匹配成功的前提下,尽可能多的匹配,也就是所谓的“贪婪”,通俗点讲,就是看到想要的,有多少就捡多少,除非再也没有想要的了。

正则表达式二采用的是非贪婪模式,在匹配到第一个“
相关标签: abcd PHP