用span标记包裹拉丁字符序列

时间:2014-06-09 10:13:05

标签: php regex

我需要preg_replace的模式,用标签<span class="text=arial"></span>包装整个HTML页面中的所有拉丁字符和数字序列。 例如,以下HTML部分

<a href="http://domain.com/path" target="_blank">GSPd 役に立つツール: スキル意欲マトリクス</a>

应替换为:

<a href="http://domain.com/path" target="_blank"><span class="text=arial">GSPd</span> 役に立つツール: スキル意欲マトリクス</a>

显然,只有内部节点文本应该以这种方式处理,因此替换不会破坏HTML标记。

我尝试过的事情:

$p = '#(?<=\>)([a-zA-Z0-9]+)(?=\<)#ium';
$html = preg_replace(
    $p,
    '><span class="text-arial">$0</span><',
    $html
);

此模式应扩展为包含内容由混合字符组成的情况,例如GSPd 役に立つツール: スキル意欲マトリクス 100

2 个答案:

答案 0 :(得分:1)

要在<tag>内跳过文字时匹配字母和数字,您可以使用可爱的(*SKIP)(*F)技术(在Perl和PCRE中提供),并且可以毫不费力地完成:

(?i)<[^>]*>(*SKIP)(*F)|[a-z][a-z ]+

demo上,查看替换部分。

您可以将其弹出到preg_replace:

$regex = "~(?i)<[^>]*>(*SKIP)(*F)|[a-z][a-z ]+~";
$replace = '<span class="text=arial">\0</span>';
$replaced = preg_replace($regex,$replace,$original);

它是如何运作的?

在这种情况下,您希望排除某些内容不匹配 - 在这种情况下是标记。它类似于regex-matching a pattern unless..."

这个问题

交替|的左侧匹配完整的< ... >标签,然后故意失败,引擎会跳到字符串中的下一个位置。右侧匹配“拉丁文本”(这里我定义为字母和空格,可以细化),我们知道它是正确的文本,因为它与左侧的表达不匹配。

进一步改进

您可以浏览[a-z][a-z ]+并对其进行优化,直到您确信它符合您对“拉丁文字”的定义。

参考

答案 1 :(得分:0)

我已经调整了zx81的方法,以避免处理某些标签(如样式或脚本)的文本:

    $regex = "~(?i)<(head|style|script|noscript)[^>]*?>.*?<\/.*?\\1>(*SKIP)(*F)|<[^>]*>(*SKIP)(*F)|[a-z0-9&][_a-z0-9&,.;:#%\-/\(\) ]*~smu";        
    $replace = '<span class="text-arial">\0</span>';
    $html = preg_replace($regex,$replace,$html);

需要什么

客户要求将MS P Gothic用于日文字符,将Arial用于拉丁文字符。问题在于,MS P Gothic字体已经具有拉丁字形,并且对于拉丁字符应用Arial,它们应该用一些标签包装,以便能够通过CSS应用font-family: Arial。手动添加跨度很烦人,非常感谢@ zx81提供了一个很好的解决方案!