我有一个标量中的HTML代码。HTML代码可以包含我想要替换的某个域的URL。例如:
my $code = <<ENDCODE;
<img src="http://server1.olddomain.com/image1.jpg">
<img src="http://server5.otherdomain.com/image2.jpg">
<img src="http://server2.olddomain.com/image3.jpg">
ENDCODE
URL的服务器部分可以是任何东西(所以不一定是“www”)。我希望将所有指向www.example.com的图像URL替换为newdomain.com,但前提是图像存在于newdomain.com上。所以我不能简单地直接替换,而是需要调用一个函数(执行必要的检查)。所以我想我会这样做:olddomain.com
$code =~ s/src=\"(.+?\.olddomain\.com\/.+?)\"/URLReplace($1)/gsie;
URLReplace是一个函数,它会执行所有检查并在必要时替换URL。问题是正则表达式会找到两个匹配项:
http://www.olddomain.com/image1.jpg
和
http://www.otherdomain.com/image2.jpg">\n<img src="http://www.olddomain.com/image3.jpg
当然,问题是第一个.+?
捕获了下一个“. olddomain.com“之前的所有内容,在第二个匹配中,它是http://www.somedomain.com/image2.jpg">\n<img src="http://www
。
那么我该如何解决这个问题呢?
3条答案
按热度按时间oxf4rvwz1#
除了正则表达式,你可以使用DOM来改变HTML。Mojo::DOM支持CSS选择器来匹配属性中的子字符串。一旦你找到了你想要改变的节点,你可以使用Mojo::URL(或任何URI lib)的功能来替换主机名:
输出显示了域的选择性更新:
诀窍在于每个阶段都会限制效果,这样你就不会遇到你不想改变的文本。你知道你有一个
src
的img
标签,它有你想要的子字符串,然后你知道你只处理src
值,然后你知道你只处理URL的host
部分。我有很多Mojolicious Web UserAgents中DOM解析和修改的例子。
cmssoen22#
如果不想让
.
匹配换行符,就不要使用/s
。使用
.
通常过于笼统。如果您知道URL被双引号包围,则可以将其替换为[^"]
:kcrjzv8t3#
我找到了一个解决方案:
因使用
我应该用
不同之处在于,我现在使用
[^\.]
,而不是.
(匹配任何字符),它匹配任何字符 * 但 * 点。所以它在遇到第一个点时停止匹配。