长时间的潜伏,第一次海报 - 请光临我,我是一个正则表达式n00b,但我对项目的某些功能有一个好主意,我试图尽我所能地实现它但我需要一些帮助来达到预期的效果。有问题的页面是:http://dev.favorcollective.com/guidelines/(仅提供一些上下文)
我正在使用php的preg_replace来浏览特定页面的内容(巨型字符串),我正在搜索词汇表术语,然后用一些html包装这些术语,从而启用动态词汇表定义工具提示。
这是我目前的代码:
function annotate($content)
{
global $glossary_terms;
$search = array();
$replace = array();
$count=1;
foreach ($glossary_terms as $term):
array_push($search,'/\b('.preg_quote($term['term'],'/').')[?=a-zA-Z]*/i');
$id = "annotation-".$count;
$replacement = '<a href="'.get_bloginfo('url').'/glossary#'.preg_replace( '/\s+/', '', $term['term']).'" class="annotation" rel="'.$id.'">'.$term['term'].'</a><span id="'.$id.'" style="display:none;"><span class="term">'.$term['term'].'</span><span class="definition">'.$term['def'].'</span></span>';
array_push($replace,(string)$replacement);
$count++;
endforeach;
return preg_replace($search, $replace, $content);
}
•但是如果我想忽略&lt; h#&gt;中的匹配怎么办? &LT; /小时#&GT;标签
•我还有一个特定的字符串,我不希望在其中匹配特定术语。例如,我想在“ACTFL熟练度指南”的上下文中使用“熟练度”这个词来匹配任何时候我如何在正则表达式中添加例外?这甚至是一种选择吗?
•最后,如何将匹配的文本作为变量返回?目前,当我匹配以's'或'ing'结尾的术语(故意)时,我的脚本打印匹配的术语而不是匹配的原始字符串(即它将“描述”替换为“描述”)。反正有吗?
谢谢!
答案 0 :(得分:3)
不是一个php家伙(c#),但是这里有。我认为:
'/\b('.preg_quote($term['term'],'/').')[?=a-zA-Z]*/i'
将映射到这个更具可读性的模式:
/\b(ESCAPED_TERM)[?=a-zA-Z]*/i
所以,只要排除&lt; h#&gt;只有当你可以假设你的数据是简单的非嵌套的情况时,正则表达式才是正确的:&lt; h#&gt; TERM&lt; h#&gt;。如果可以的话,你可以使用负前瞻断言:
/\b(ESCAPED_TERM)(?!<h\d>)[?=a-zA-Z]*/i
您可以使用lookahead with a lookbehind来处理您的特殊情况:
/\b(ESCAPED_TERM|(?<!ACTFL )Proficiency(?!\sGuidelines))(?!<h\d>)[?=a-zA-Z]*/i
注意:如果你有一堆这些特殊情况,PHP可能(应该)有一个“忽略空白”标志,它可以让你将每个标记放在换行符上。
答案 1 :(得分:0)
正则表达式很精彩,很棒,很神奇。但一切都有其局限性。
这就是为什么拥有像PHP这样的语言来提供额外功能的好处。 :)
你能用非贪婪的正则表达式删除标题吗?
$content = preg_replace('/<h[1-6]>.*?<\/h[1-6]>/sim', "", $content);
如果非贪婪的评估不起作用,那么假设标题中没有任何其他HTML会怎么样?
$content = preg_replace('/<h[1-6]>[^<]*<\/h[1-6]>/im', "", $content);
另外,您可能希望使用sprintf来简化替换:
/*
1 get_bloginfo('url')
2 preg_replace( '/\s+/', '', $term['term']).
3 $id
4 $term['term']
5 $term['def']
*/
$rfmt = '<a href="%1$s/glossary#%2$s" class="annotation" rel="%3$s">%4$s</a><span id="%3$s" style="display:none;"><span class="term">%4$s</span><span class="definition">%5$s</span></span>';
...
$replacement = sprintf($rfmt, get_bloginfo('url'), preg_replace( '/\s+/', '', $term['term']), $id, $term['term'], $term['def'] );