2011-12-15 95 views
1

长时间的潜伏者,第一次海报 - 请裸露在我身边,我是一个正则表达式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); 
} 

•但是,如果我想忽略的<^h#> </H#>标签内的比赛是什么?

•我也有一个特殊的字符串,我不想要一个特定的术语来匹配。例如,我希望“熟练程度”一词在任何时候与“ACTFL熟练程度指南”中不使用的时候匹配,我将如何着手为我的正则表达式添加例外情况?这甚至是一个选择吗?

•最后,如何将匹配的文本作为变量返回?目前,当我匹配以's'或'ing'结尾的术语(故意使用)时,我的脚本将打印匹配的术语而不是匹配的原始字符串(即将其替换为“description”和“description”)。无论如何要这样做?

谢谢!

+1

欢迎SO!有关使用正则表达式处理HTML的信息,请阅读[本介绍性文章](http://stackoverflow.com/a/1732454/596781)。 – 2011-12-15 17:46:34

回答

3

不是一个PHP的家伙(C#),但在这里。我认为:

'/\b('.preg_quote($term['term'],'/').')[?=a-zA-Z]*/i'将映射到这个更具可读性模式:

/\b(ESCAPED_TERM)[?=a-zA-Z]*/i 

所以,尽量排除<^h#>类型的变量,正则表达式是确定只有在你认为你的数据会简单,非嵌套案例:< h#> TERM < h#>。如果可以的话,你可以使用负前瞻断言:

/\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可能(应该)有一个“忽略空白”标志,它可以让你把每个标记放在换行符上。

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']); 
相关问题