用RegExps替换PHP中包含的标签

时间:2009-04-06 20:55:32

标签: php regex preg-replace preg-match

我需要读取字符串,检测{VAR},然后执行file_get_contents('VAR.php')代替{VAR}。 “VAR”可以命名为任何东西,比如TEST或CONTACT-FORM等。我不想知道VAR是什么 - 不是做硬编码的条件,而只是看到一个大写的字母数字标签包围花括号,只需要一个file_get_contents()来加载它。

我知道我需要使用preg_match和preg_replace,但是我在这上面遇到了RegExps。

这有用吗?它对于挂钩WordPress非常有用。

5 个答案:

答案 0 :(得分:1)

你需要做很多事情。我假设您可以做一些工作,以便将要预处理的页面数据转换为字符串。

  1. 首先,您需要正则表达式才能正确匹配。使用像/{\w+}/这样的东西应该相当容易。

  2. 接下来,您需要使用preg_match的所有标志来获取页面数据中的偏移位置。此偏移量可让您将字符串分为匹配的前一部分,匹配部分和后部分。

  3. 一旦你有3个部分,你需要运行你的包,并将它们粘在一起。

  4. 泡沫,冲洗,重复。

  5. 找不到更多变量时停止。

  6. 这不是非常有效,而且可能有更好的方法。您可能希望考虑在/[{}]/上进行preg_split分割。无论你如何分割它,你都假设你可以信任你输入的数据,这将简化整个过程。为此,我将如下列出代码:

    1. 获取您的内容并将其拆分为:$parts = preg_split('/[{}]/', $page_string);

    2. 使用以下标准在部件上编写递归函数:

      • 当arg的长度<1时停止。 3
      • 否则,返回一个由
      • 组成的新数组
      • $ arg [0]。 load_data($ arg [1])。 $ ARG [2]
      • 加上$ argv [3 ...]
      • 中剩余的内容
    3. 在$ parts上运行您的功能。

答案 1 :(得分:1)

上面的Orion有一个正确的解决方案,但在你的简单案例中并没有必要使用回调函数。

假设文件名是A-Z +连字符,你可以在正则表达式中使用PHP的/ e标志在1行中完成:

$str = preg_replace('/{([-A-Z]+)}/e', 'file_get_contents(\'$1.html\')', $str);

这将用VAR.html的内容替换{VAR}的任何实例。如果需要指定特定目录,可以将路径作为第二项的前缀。

如上所述存在同样模糊的安全担忧,但我无法想到任何具体内容。

答案 2 :(得分:0)

你可以在没有正则表达式的情况下做到这一点(上帝保佑),例如:

//return true if $str ends with $sub
function endsWith($str,$sub) {
    return ( substr( $str, strlen( $str ) - strlen( $sub ) ) === $sub );
}

$theStringWithVars = "blah.php cool.php awesome.php";
$sub = '.php';
$splitStr = split(" ", $theStringWithVars);
for($i=0;$i<count($splitStr);$i++) {
    if(endsWith(trim($splitStr[$i]),$sub)) {
        //file_get_contents($splitStr[$i]) etc...
    }    
}

答案 3 :(得分:0)

离开我的头顶,你想要这个:

// load the "template" file
$input = file_get_contents($template_file_name);

// define a callback. Each time the regex matches something, it will call this function.
// whatever this function returns will be inserted as the replacement
function replaceCallback($matches){
  // match zero will be the entire match - eg {FOO}. 
  // match 1 will be just the bits inside the curly braces because of the grouping parens in the regex - eg FOO
  // convert it to lowercase and append ".html", so you're loading foo.html

  // then return the contents of that file.
  // BEWARE. GIANT MASSIVE SECURITY HOLES ABOUND. DO NOT DO THIS
  return file_get_contents( strtolower($matches[1]) . ".html" );
};
// run the actual replace method giving it our pattern, the callback, and the input file contents
$output = preg_replace_callback("\{([-A-Z]+)\}", replaceCallback, $input);

// todo: print the output

现在我将解释正则表达式

 \{([-A-Z]+)\}
  • \{\}只是告诉它与花括号相匹配。您需要斜杠,因为{}是特殊字符,因此需要转义。
  • ()创建分组。基本上,这可以让你提取匹配的特定部分。我在上面的函数中使用它来匹配大括号内的东西,而不匹配大括号本身。如果我没有这样做,那么我需要从匹配中删除{},这会很烦人
  • [-A-Z]表示“匹配任何大写字母或-
  • +之后的[-A-Z]表示我们需要至少包含1个字符,但我们可以拥有任意数字。

答案 4 :(得分:0)

相比较而言,正则表达式很昂贵。虽然您可能需要它们来确定要加载哪些文件,但您当然不需要它们来进行替换,并且可能不应该使用正则表达式。毕竟,你确切知道你要替换的是什么,为什么你需要模糊搜索?

使用关联数组和str_replace进行替换。 str_replace支持一次执行多个替换的数组。一行替换,无循环。

例如:

$substitutions = array('{VAR}'=>file_get_contents('VAR.php'),
'{TEST}'=>file_get_contents('TEST.php'),
...
);

$outputContents = str_replace( array_keys($substitutions), $substitutions, $outputContents);