用PHP检测标签的最佳方法是什么?

时间:2010-12-23 06:15:10

标签: php regex performance

我希望用户能够插入如下标签:

Lorem ipsum dolor sit amet, {module_user_name, 123} consectetur adipiscing elit.

正如您在上面的示例中所看到的,标记有几个参数。第一个是所需的功能,参数将取决于所请求的功能。

所以我会使用正则表达式来检测{和},反馈?然后我会抓住第一个参数并检查它是否存在。

如果确实存在,我会使用一个好的命名约定来避免使用大量的IF ELSE或切换脚本。像module_user_name一样会触发moduleUserName()函数,或类似的东西,反馈?

**这只是我对如何解决这个问题的想法,我只是想知道是否有人可以改进它或指出速度等问题。

3 个答案:

答案 0 :(得分:2)

我认为标签是指某种形式的插件标记。然后{语法有点过于轻量级,可能很容易与常规文本冲突;为什么替换应该谨慎进行。这里的一个好方法就是像这样使用preg_replace_callback()

 $html = preg_replace_callback('/\{([\w\s,\d]+)\}/', "tags_", $html);

 function tags_($call) {

     // split up
     $func = explode(",", $call[1]);
     $func = array_map("trim", $func);

     // test for handler existence
     if (function_exists($func[0])) {
         return call_user_func_array(array_shift($func), $func);
     } 

     return $call[0];   // do not replace
 }

如果存在,则只调用指定的用户函数。如果找到{wacky text 123}之类的内容,那么回调只会返回它,从而使原始的$html保持不变。

答案 1 :(得分:2)

我的建议非常接近马里奥已经给你的东西,但我想补充一下:

  • 你应该对正则表达式更加详细,以便忽略看起来不像函数的东西(例如{12345})

  • 如果你真的必须将“module_user_name”翻译成“moduleUserName”,那么你应该把它设置为一个数组,而不是一个开关:

    $ tags = array(         / * user tag => php函数* /         'module_user_name'=> 'moduleUserName',         'module_user_id'=> 'getUserId',         //等         ); if(isset($ tags [$ func])){     call_user_func($ tags [$ func],...) }

避免使用switch()的原因是因为它像一堆if / elseif语句一样执行,并且到达底部的情况需要更长的时间,而数组有不断的查找时间(我很确定是这种情况)

  • 如果您不想维护一个巨大的数组(我不会),那么只需决定您将用于每个用户标记的前缀,以便{module_user_name, 123}转换为php { {1}}并且只调用以USER_TAG_module_user_name(123)开头的函数。

  • 不要忘记为用户提供一种方法USER_TAG_,而不会将其转换为其他内容(即使用{{{

答案 2 :(得分:0)

  

如果确实存在,我会用一个好的   命名约定以避免必须   使用大量IF ELSE或开关   脚本。就像module_user_name一样   触发moduleUserName()函数,或   类似的东西,反馈?

这听起来像是自动加载器上的一个变体,每个名称都映射到一个类/函数。如果您完全控制命名,那应该不是问题。如果必须支持现有标记和/或命名约定不一致,则需要switch语句或类似标记。

实际上,这类似于Smarty进行函数调用的方式。与编写自己的解析器相反,您可以探索它。它的实现是完善的,可能比你第一次写的更好。