Php 可以使用Regex/preg_replace向关键字添加锚定标记吗?
我想能够切换这个Php 可以使用Regex/preg_replace向关键字添加锚定标记吗?,php,regex,Php,Regex,我想能够切换这个 My sample[a id=“keyword”href=“someURLkeyword”]测试关键字测试[/a]将此关键字链接到此处。 到 我的示例[a id=“keyword”href=“someURLkeyword”]测试关键字测试[/a]将此[a href=“url”]关键字[/a]链接到此处。 我不能简单地替换“关键字”的所有实例,因为有些实例在现有锚定标记中使用 注意:在Linux上使用PHP5 preg\u replace。单用正则表达式无法做到这一点。正则表达式
My sample[a id=“keyword”href=“someURLkeyword”]测试关键字测试[/a]将此关键字链接到此处。
到
我的示例[a id=“keyword”href=“someURLkeyword”]测试关键字测试[/a]将此[a href=“url”]关键字[/a]链接到此处。
我不能简单地替换“关键字”的所有实例,因为有些实例在现有锚定标记中使用
注意:在Linux上使用PHP5 preg\u replace。单用正则表达式无法做到这一点。正则表达式是上下文无关的——它们只是匹配一个模式,而不考虑环境。要做您想做的事情,您需要将源解析为抽象表示,然后将其转换为目标输出。单用正则表达式无法做到这一点。正则表达式是上下文无关的——它们只是匹配一个模式,而不考虑环境。要执行所需操作,需要将源解析为抽象表示,然后将其转换为目标输出。使用正则表达式可能不是解决此问题的最佳方法,但这里有一个快速解决方案:
function link_keywords($str, $keyword, $url) {
$keyword = preg_quote($keyword, '/');
$url = htmlspecialchars($url);
// Use split the string on all <a> tags, keeping the matched delimiters:
$split_str = preg_split('#(<a\s.*?</a>)#i', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
// loop through the results and process the sections between <a> tags
$result = '';
foreach ($split_str as $sub_str) {
if (preg_match('#^<a\s.*?</a>$#i', $sub_str)) {
$result .= $sub_str;
} else {
// split on all remaining tags
$split_sub_str = preg_split('/(<.+?>)/', $sub_str, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($split_sub_str as $sub_sub_str) {
if (preg_match('/^<.+>$/', $sub_sub_str)) {
$result .= $sub_sub_str;
} else {
$result .= preg_replace('/'.$keyword.'/', '<a href="'.$url.'">$0</a>', $sub_sub_str);
}
}
}
}
return $result;
}
函数链接\u关键字($str,$keyword,$url){
$keyword=preg_quote($keyword,“/”);
$url=htmlspecialchars($url);
//在所有“,$sub_sub_str)上使用拆分字符串;
}
}
}
}
返回$result;
}
一般的想法是将字符串拆分为链接和其他所有内容。然后将链接标记之外的所有内容拆分为标记和纯文本,并将链接插入纯文本。这将阻止[p class=“keyword”]扩展为[p class=“[a href=“url”]关键字[/a]”
同样,我会尝试找到一个不涉及正则表达式的简单解决方案。使用正则表达式可能不是解决此问题的最佳方法,但这里有一个快速解决方案:
function link_keywords($str, $keyword, $url) {
$keyword = preg_quote($keyword, '/');
$url = htmlspecialchars($url);
// Use split the string on all <a> tags, keeping the matched delimiters:
$split_str = preg_split('#(<a\s.*?</a>)#i', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
// loop through the results and process the sections between <a> tags
$result = '';
foreach ($split_str as $sub_str) {
if (preg_match('#^<a\s.*?</a>$#i', $sub_str)) {
$result .= $sub_str;
} else {
// split on all remaining tags
$split_sub_str = preg_split('/(<.+?>)/', $sub_str, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($split_sub_str as $sub_sub_str) {
if (preg_match('/^<.+>$/', $sub_sub_str)) {
$result .= $sub_sub_str;
} else {
$result .= preg_replace('/'.$keyword.'/', '<a href="'.$url.'">$0</a>', $sub_sub_str);
}
}
}
}
return $result;
}
函数链接\u关键字($str,$keyword,$url){
$keyword=preg_quote($keyword,“/”);
$url=htmlspecialchars($url);
//在所有“,$sub_sub_str)上使用拆分字符串;
}
}
}
}
返回$result;
}
一般的想法是将字符串拆分为链接和其他所有内容。然后将链接标记之外的所有内容拆分为标记和纯文本,并将链接插入纯文本。这将阻止[p class=“keyword”]扩展为[p class=“[a href=“url”]关键字[/a]”
同样,我会尝试找到一个不涉及正则表达式的更简单的解决方案。不能使用“向前看”和“向后看”功能来解释匹配模式的周围环境吗?您可能可以使用“向后看”,但这将是非常困难的。我建议你调查一下preg_replace_回调。搜索完整的锚元素或关键字。如果匹配锚元素,请将其重新插入;如果您匹配一个裸关键字,请添加标记。不能使用“向前看”和“向后看”功能来说明匹配模式的周围环境吗?您可能可以使用“向后看”,但这将是非常困难的。我建议你调查一下preg_replace_回调。搜索完整的锚元素或关键字。如果匹配锚元素,请将其重新插入;如果匹配裸关键字,则添加标记。