0

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

我知道我需要使用 preg_match 和 preg_replace,但我在这方面的 RegExps 中磕磕绊绊。

这有什么用?它在挂钩 WordPress 时很有用。

4

5 回答 5

1

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

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

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

  3. 一旦你有了这 3 个部分,你需要运行你的包含,并将它们重新组合在一起。

  4. 起泡,冲洗,重复。

  5. 当您没有发现更多变量时停止。

这不是非常有效,并且可能有更好的方法。您可能希望考虑做一个 preg_split 代替,在/[{}]/. 无论您如何分割它,您都假设您可以信任您的传入数据,这将大大简化整个过程。为此,我会像这样布置代码:

  1. 获取您的内容并像这样拆分它:$parts = preg_split('/[{}]/', $page_string);

  2. 在具有以下条件的部分上编写递归函数:

    • 当 arg 的长度 < 3 时停止
    • 否则,返回一个由以下组成的新数组
    • $arg[0] 。加载数据($arg[1])。$arg[2]
    • 加上 $argv[3...] 中剩下的东西
  3. 在 $parts 上运行你的函数。

于 2009-04-06T21:03:32.930 回答
1

上面的 Orion 有一个正确的解决方案,但在您的简单情况下,实际上没有必要使用回调函数。

假设文件名是 AZ + 连字符,您可以使用正则表达式中的 PHP /e 标志在 1 行中执行此操作:

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

这会将 {VAR} 的任何实例替换为 VAR.html 的内容。如果需要指定特定目录,可以在第二个术语中添加路径前缀。

存在与上述相同的模糊安全担忧,但我想不出任何具体的东西。

于 2009-04-06T23:33:34.740 回答
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...
    }    
}
于 2009-04-06T21:07:13.953 回答
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 个字符,但我们最多可以有任意数量。
于 2009-04-06T21:08:16.447 回答
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);
于 2009-04-06T23:55:32.597 回答