1

我在 php 中有一个变量 ($output),它包含将呈现给浏览器的所有 html 页面,但我需要用 data:image 替换所有图像 src 以使延迟加载 js 工作。

要求是:

  • img src 没有相同的结构,我们有:

    <img src="img.jpg" alt='' />

    <img alt="text" src='img.gif'>

    <img class="myclass" src="img.png" alt='' />

    ... ETC

  • 我只想替换 <body {can have optional text}> 和 </body> 之间的图像

  • 不要在 <script {optional text here}> 和 </script> 之间替换 img 标签

谢谢

4

1 回答 1

0

很多人在使用正则表达式时所犯的错误是试图编写一个可以处理所有事情的巨大正则表达式。这种方式是疯狂的。这不仅可能是不可能的(取决于问题),而且会很复杂、丑陋和脆弱。将事情分解成可管理的步骤要好得多。

你说你只想替换<img>标签内<body>,但唯一有效<img>的地方标签是内,所以我将忽略这一点。如果您确实需要忽略之外的标签,则可以将整个内容包装在另一个中以从您的输入中提取出来。<body><img><body>preg_replace_callback<body>

因此,我采用的方法是使用两个正则表达式:一个匹配<img>输入中标签的所有实例,另一个替换alt属性。为此,我使用preg_replace_callback

$output = preg_replace_callback( '/<img .*?>/', function($matches) {
        return preg_replace( '/\bsrc\s*=\s*[\'"](.*?)[\'"]/', 
            'data-image="$1"', $matches[0] );
}, $input );

注意在?重复元字符上使用惰性量词*:没有这个,两个连续的<img>标签将被视为一个大标签,这不是我们想要的。在替换函数中,我查找src属性并将其替换为data-image属性。

这是此解决方案将失败的地方:

  • 如果引号分隔的src属性 ( <img src="what's_up_doc.jpg">) 中有撇号,反之亦然。如果你需要解决这个问题,你必须有两个不同的替换正则表达式,一个处理双引号属性,一个处理单引号属性。
  • 如果您的<img>标签跨越多行。如果这是一个问题,在外部正则表达式中,您可以使用[^]而不是.匹配所有内容,包括换行符。
于 2013-07-07T20:48:21.200 回答