2013-02-14 81 views
3

好吧我彻底在为什么这个正则表达式的作品。我正在使用的文字是这样的:这个正则表达式为什么起作用?

<html> 
    <body> 
    hello 
    <img src="withalt" alt="hi"/>asdf 
    <img src="noalt" />fdsa<a href="asdf">asdf</a> 
    <img src="withalt2" alt="blah" /> 
    </body> 
</html> 

使用下面的正则表达式(在PHP中测试,但我猜想这是适用于所有的Perl的正则表达式),它将返回不包含所有的img标签一个ALT标签:

/<img(?:(?!alt=).)*?>/ 
Returns: 
<img src="noalt" /> 

所以基于这样我会觉得简单地删除无反向引用将返回相同的:

/<img(?!alt=).*?>/ 
Returns: 
<img src="withalt" alt="hi"/> 
<img src="noalt" /> 
<img src="withalt2" alt="blah" /> 

正如你看到的,而不是它只是返回所有图片标签。然后让事情变得更加混乱,删除? (一个简单的通配符,据我所知)的*返回到最后后>

/<img(?!alt=).*>/ 
Returns: 
<img src="withalt" alt="hi"/> 
<img src="noalt" />fdsa<a href="asdf">asdf</a> 
<img src="withalt2" alt="blah" /> 

因此,任何人照顾通知我,或者至少指向我怎么在这里上的方向是正确的?

+0

2013年。使用XML解析器。 – 2013-02-14 21:45:43

+0

哈,那个html只是我写的真正快速的东西来测试别人的正则表达式。 – Eric 2013-02-14 22:09:04

回答

2
/<img(?:(?!alt=).)*?>/ 

此正则表达式适用于每次img后一致字符负前瞻。所以,一旦发现alt=,它就会停止。因此,它只会匹配img标签,该标签没有alt属性。

/<img(?!alt=).*?>/ 

此正则表达式,只是应用负前瞻img后。因此,无论alt=是否出现在字符串下方的任何位置,它都会匹配所有img标签之前的所有标签之前的所有内容,直到第一个>标签不被alt=跟随。它将.*?

/<img(?!alt=).*>/ 

这是一样的前一个被覆盖,但它匹配的一切,直到最后>,因为它使用greedy matching。但我不知道你为什么得到那个输出。你应该已经得到了一切,直到</html>的最后>


现在忘了,在那里发生的一切,并走向一个HTML Parser,用于解析HTML。他们专门为这项任务而设计。所以,不要打扰使用正则表达式,因为你不能通过正则表达式来解析各种HTML。

+0

所以你说的是第二个(非贪婪的)正则表达式匹配所有东西,直到第一个>,然后验证整个。*不是以alt =开头。所以确定一切都有道理。至于贪婪,我将不得不对此进行研究,因为它似乎比我记得的要深入得多。谢谢! – Eric 2013-02-14 22:07:33

+1

@Eric。不,它首先验证'img'后面没有'alt =',然后只有它进一步匹配所有东西,直到第一个'>'。 – 2013-02-14 22:08:49

+0

哦,对,这是有道理的,因为它是一个先行,而不是后视。就正则表达式的速度而言,它也更有用。哦,我认为第三个正则表达式不匹配到的原因是因为php的preg_match_all()函数。如果我记得对,它只是逐行匹配。 – Eric 2013-02-14 22:11:26

相关问题