PHP中保留含artworks的<g><image>标签,移除其余同类标签
解决SVG中移除指定标签的PHP方案
我明白你的需求:要清理SVG文件,移除所有包含<image>的<g>标签,但要保留那些<image>的href(包括xlink:href)里含有"artworks"的<g>。用正则处理确实方便,但现有正则没做过滤,我来帮你调整一下,同时也给你更可靠的DOM解析方案。
方法一:改进正则表达式(适合简化后的无换行SVG)
你之前的正则能匹配所有带<image>的<g>,但需要加入否定前瞻来排除href包含"artworks"的情况。以下是调整后的正则和PHP代码:
// 假设$svgContent是已经移除换行的SVG内容 $svgContent = file_get_contents('your-file.svg'); // 正则匹配:包含<image>但href不含"artworks"的<g>标签 $pattern = '/<g transform="[^"]*">.*?<image[^>]*?(?:href|xlink:href)="(?!.*artworks)[^"]*"[^>]*?>.*?<\/g>/s'; $cleanedSvg = preg_replace($pattern, '', $svgContent); // 保存处理后的SVG file_put_contents('cleaned-file.svg', $cleanedSvg);
正则说明:
<g transform="[^"]*">:匹配带transform属性的<g>开头(如果你的<g>可能没有transform,可以改成<g[^>]*>).*?:非贪婪匹配,避免跨标签匹配<image[^>]*?(?:href|xlink:href)="(?!.*artworks)[^"]*"[^>]*?>:匹配<image>标签,且其href/xlink:href属性值不包含"artworks"((?!.*artworks)是关键的否定前瞻)/s修饰符:让.匹配换行符(即使你移除了换行,加上更稳妥)
方法二:用DOMDocument解析(更可靠,推荐)
正则处理XML/SVG有局限性——如果标签嵌套复杂、属性顺序变化或存在特殊字符,正则很容易失效。用PHP的DOM扩展解析是更规范的方式:
$svgContent = file_get_contents('your-file.svg'); $dom = new DOMDocument(); // 忽略SVG解析时的非致命警告(因为SVG可能有不符合严格XML的地方) libxml_use_internal_errors(true); $dom->loadXML($svgContent); libxml_clear_errors(); $xpath = new DOMXPath($dom); // XPath查询:找到所有包含<image>的<g>,且<image>的href/xlink:href不含"artworks" $gNodes = $xpath->query('//g[image[not(contains(@href, "artworks") or contains(@xlink:href, "artworks"))]]'); // 遍历并移除这些<g>标签 foreach ($gNodes as $gNode) { $gNode->parentNode->removeChild($gNode); } // 输出处理后的SVG $cleanedSvg = $dom->saveXML(); file_put_contents('cleaned-file.svg', $cleanedSvg);
这个方法能准确识别SVG的结构,不用担心标签格式变化导致的匹配错误,适合复杂的SVG文件。
内容的提问来源于stack exchange,提问作者Yvon Huynh
相关产品推荐
相关产品推荐

