我有一个PHP变量中的HTML代码,我需要替换包含在另一个标签中的每个链接,该标签具有"obfuscate"
类,例如:
<div class="obfuscate foobar">
<strong>
<a href="https://example.com" class="randomclass" target="_BLANK">test</a>
</strong>
</div>
我需要将<a>
标记替换为<span>
,它继承了原始标记的所有内容,添加了"akn-obf-link"
类,并在"data-o"
属性下通过base64_encode()
传递了一个模糊链接,如果链接具有target _blank或"0"
,则"data-b"
属性的值为"1"
。
在上面的示例中,<a>
标记应转换为:
<span class="akn-obf-link randomclass" data-o="aHR0cHM6Ly9leGFtcGxlLmNvbQ==" data-b="1">test</span>
我已经有一个代码,当<a>
标签本身有"obfuscate"
类时,如果这可能有帮助:
$result = preg_replace_callback('#<a[^>]+((?<=\s)href=(\"|\')([^\"\']*)(\'|\")[^>]+(?<=\s)class=(\"|\')[^\'\"]*(?<!\w|-)obfuscate(?!\w|-)[^\'\"]*(\"|\')|(?<=\s)class=(\"|\')[^\'\"]*(?<!\w|-)obfuscate(?!\w|-)[^\'\"]*(\"|\')[^>]+(?<=\s)href=(\"|\')([^\"\']*)(\'|\"))[^>]*>(.*)<\/a>#miUs', function($matches) {
preg_match('#<a[^>]+(?<=\s)class=[\"|\\\']([^\\\'\"]+)[\"|\\\']#imUs',$matches[0],$matches_classes);
$classes = trim(preg_replace('/\s+/',' ',str_replace('obfuscate','',$matches_classes[1])));
return '<span class="akn-obf-link'.($classes?' '.$classes:'').'" data-o="'.base64_encode($matches[3]?:$matches[10]).'" data-b="'.((strpos(strtolower($matches[0]),'_blank')!==false)?'1':'0').'">'.$matches[12].'</span>';
}, $code);
我需要相同的,但每当标签是在另一个标签,有"obfuscate"
类。
1条答案
按热度按时间p3rjfoxz1#
试图用正则表达式解决这个问题将是痛苦和不安全的,原因在Stackoverflow上讨论了很多次。
通常,如果
<div class="obfuscate">
包含一些子<div>
标记,会发生什么?这意味着你必须在正则表达式中处理递归,因为this regex将不起作用:
作为we can see here,它不能捕获div的全部内容。你需要一个平衡良好的正则表达式来解决这个问题。
好的,让我们假设你有一个
class="..."
属性,就像在一部很好的老浪漫电影中一样,带有漂亮的双引号。我们假设你没有子div。这意味着你可以捕获内部的HTML,然后用一个相对复杂的模式来查找所有<a>
标签,就像下面这样:我在这里做的:https://regex101.com/r/ZSx69l/2
我想处理带双引号、单引号和不带引号的属性。我试图捕获不带引号的值,但没有找到正确的方法。没关系,因为使用
preg_replace_callback()
函数,您可以使用trim(..., '"\'')
或正则表达式删除引号。然后您就可以计算base64并将其重写为所需的输出。但这真的能解决所有格式错误的HTML代码吗?可能不会。
我会坚持使用PHP's DOMDocument,因为它有一些安全的东西。现在到处都安装了它,与bug的风险相比,执行时间并不重要。
您可能不需要解析HTML页面的全部内容,而需要使用防弹正则表达式来获取所需内容。