在\S正则匹配中排除字符

1 投票
6 回答
6875 浏览
提问于 2025-04-11 20:56

我有一个正则表达式,用来匹配HTML链接:

<a\s*href=['|"](http:\/\/(.*?)\S['|"]>

这个表达式有点用,但其实并不完全好用。因为它会把< a href...后面的所有内容都抓取到,结果就是一直往后抓。我想把最后一个\S匹配中的引号字符排除掉。有没有办法做到这一点呢?

补充:这样的话,它就只会抓到引号之前的内容,而不是< a href后面的所有东西了。

6 个回答

1
>>> import re
>>> regex = '<a\s+href=["\'](http://(.*?))["\']>'
>>> string = '<a href="http://google.com/test/this">'
>>> match = re.search(regex, string)
>>> match.group(1)
'http://google.com/test/this'
>>> match.group(2)
'google.com/test/this'

解释:

 \s+   = match at least one white space (<ahref) is a bad link
 ["\'] = character class, | has no meaning within square brackets
         (it will match a literal pipe "|")
3

\S 匹配任何不是空格的字符,就像 [^\s] 一样。

这样写的话,你可以很容易地排除引号: [^\s"']。

注意,你可能还需要对正则表达式中的 .*? 进行同样的处理。点号(.)匹配任何不是换行符的字符,就像 [^\r\n] 一样。

同样,这样写的话,你可以轻松排除引号: [^\r\n'"]。

4

我觉得你的正则表达式可能没有达到你想要的效果。

<a\s*href=['|"](http:\/\/(.*?)\S['|"]>

这个表达式会从 http:// 开始,尽量少地捕捉到第一个非空字符,直到遇到引号、单引号或管道符号为止。说实话,我也不太确定它是怎么解析的,因为似乎没有足够的右括号。

如果你想抓取 href 属性,可以试试下面这个:

<a .*?+href=['"](http:\/\/.*?)['"].*?>

这个表达式使用了 .*?(非贪婪匹配任何东西),这样可以兼容其他属性(比如 target、title 等等)。它会匹配以单引号或双引号开头和结尾的 href(不区分是哪个,引号可以是开一个类型,闭合时用另一种)。

撰写回答