简体   繁体   English

PHP正则表达式模式,用于将preg_replace_callback用于eval html的if / else条件

[英]PHP regex pattern for using preg_replace_callback to eval html's if/else condition

I want to have a regex pattern to evaluate the if/else in manually-created html tags like this: 我想有一个正则表达式模式来评估手动创建的html标签中的if / else,如下所示:

<if condition="$condition">
    Return value if true
<else/>
    Return value if false
</if>

And, more specifically: 而且,更具体地说:

<if condition="$condition">
    Return value if true
<elseif condition="$another_condition"/>
    Return value if the above is true
<elseif condition="$more_condition"/>
    Return value if the above is true
<else/>
    Return value if non of the above is true
</if>

Basically, I want to get the backreferences return values of all 'conditions', and 'return values' for practicing of php variable printing to html file. 基本上,我想获取所有“条件”的反向引用返回值,以及用于将php变量打印到html文件的实践的“返回值”。 Example: 例:

  • In the first one, $2 is the $condition, $3 is the return value if true, $4 if false 在第一个中,$ 2是$ condition,$ 3是返回值(如果为true),$ 4(如果为false)
  • In the second one, $2 is the $condition, $3 is if true, $4 is the 2nd condition, $5 is return value of the above condition if matched, and so on. 在第二个条件中,$ 2是$ condition,$ 3是true,$ 4是第二条件,$ 5是上述条件的返回值(如果匹配),依此类推。

I need a pattern that can either regconize if there are any 我需要一种可以重新调节是否存在的模式

<else/>

or 要么

<else condition="blah">

or multiple appearances of it, to return properly backreferences' values. 或多次出现,以正确返回反向引用的值。

The purpose of this is to use a php file (with predefined variables) to include a html template, and print out values to it based on php variable, without directly using 这样做的目的是使用一个带有预定义变量的php文件包括一个html模板,并基于php变量将值打印出来,而无需直接使用

<?php if ($condition) { $result; } ?>

inside the html template. 在html模板中。

Example: 例:

PHP file: PHP文件:

<?php

  function callback()
  {
    $precondition  = eval('return ' . $matches[1] . ';');

    // Prewritten function for parsing boolean from string
    $condition = parse_boolean($precondition); 


    // Restrict result to boolean only
    if (is_bool($condition))
    {
        // This need better coding based on multiple <elseif ../>
        $ret = ($condition ? $matches[2] : $matches[4]);
    }

    return $ret;      
  }

  $a = 5;
  $b = 6;

  $content = file_get_contents('/html/file/path.html');

  $pattern = 'I need this pattern';
  $output  = preg_replace_callback($pattern, 'callback', $content);

  echo $output;
?>

HTML file: HTML档案:

<if condition="$a == $b">
    a is equal with b
<elseif condition="$a > $b">
    a is larger than b
<elseif condition="$a < $b">
    a is smaller than b
</if>

When running the PHP file, it will print: 运行PHP文件时,它将打印:

a is smaller than b

I hope to get a specific answer, or any else ways to fix the codes that I've written myself (not really good imho). 我希望得到一个具体的答案,或者其他任何方法来修复我自己编写的代码(不是很好的恕我直言)。

Thank you. 谢谢。

Try something like this: 尝试这样的事情:

PHP PHP

$file = file_get_contents('regexhtml.html');
$html = new DOMDocument();
$html->loadHTMLFile('regexhtml.html');

$conditions = array();
$matches = array();

$ifs = $html->getElementsByTagName('cond');

foreach ($ifs as $if_s) {
     // If
     $ifs1 = $if_s->getElementsByTagName('if');

     $counter = 0;
     foreach ($ifs1 as $if_s1) {
        $conditions[count($conditions)]['if_'.$counter] = array(
            'condition' => $if_s1->getAttribute('condition'),
            'message' => trim($if_s1->nodeValue)
        );
        $counter++;
     }


     // Else-if
     $ifs2 = $if_s->getElementsByTagName('elseif');

     $counter = 0;
     foreach ($ifs2 as $if_s2) {
        $conditions[count($conditions)]['elseif_'.$counter] = array(
            'condition' => $if_s2->getAttribute('condition'),
            'message' => trim($if_s1->nodeValue)
        );
        $counter++;
     }

     // Else
     $ifs3 = $if_s->getElementsByTagName('else');

     $counter = 0;
     foreach ($ifs3 as $if_s3) {
        $conditions[count($conditions)]['else_'.$counter] = array(
            'message' => trim($if_s1->nodeValue)
        );
        $counter++;
     }
}

echo '<pre>';
print_r($conditions);
echo '</pre>';

You will get some warnings tho, so do error_reporting('E_NONE'); 您会收到一些警告, error_reporting('E_NONE'); to ignore the invalid HTML warnings. 忽略无效的HTML警告。 As long as you have xHTML/HTML5 complaint browsers it should support custom tags. 只要您拥有xHTML / HTML5投诉浏览器,它就应支持自定义标签。

HTML (regexhtml.html) HTML(regexhtml.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Title</title>
</head>
<body>
    <cond>
        <if condition="$a == $b">
            a is equal with b
        </if>
        <elseif condition="$a > $b">
            a is larger than b
        </elseif>
        <elseif condition="$a < $b">
            a is smaller than b
        </elseif>
        <else>
            a is smaller than b
        </else>
    </cond>
</body>
</html>

Output 产量

Array
(
    [0] => Array
        (
            [if_0] => Array
                (
                    [condition] => $a == $b
                    [message] => a is equal with b
                )

        )

    [1] => Array
        (
            [elseif_0] => Array
                (
                    [condition] => $a > $b
                    [message] => a is equal with b
                )

        )

    [2] => Array
        (
            [elseif_1] => Array
                (
                    [condition] => $a < $b
                    [message] => a is equal with b
                )

        )

    [3] => Array
        (
            [else_0] => Array
                (
                    [message] => a is equal with b
                )

        )

)

You can now do with the output whatever you like. 现在,您可以根据需要使用输出。 Strip it to make regex or whatever you wish to do with it. 剥去它来制作正则表达式或任何您想使用它的方法。

To match the PHP variables (like $a ) you may need some scope manipulation; 要匹配PHP变量(如$a ),您可能需要进行一些范围操作;

// These won't practically exist, but only as strings in the Array() object
$html_a1 = '12';
$html_b1 = '23';

// Storing the string-based code into new variables
$a1 = eval('return $html_a1;');
$b1 = eval('return $html_b1;');

echo eval('return $html_a1;').'<br /><br />';

if ($a1 == $b1) {
    echo 'a is equal with b';
}
elseif ($a1 > $b1) {
    echo 'a is larger than b';
}
elseif ($a1 < $b1) {
    echo 'a is smaller than b';
}
else {
    echo 'Something else';
}

With the DOMDocument() library you can write back the outcomes instantly too if you need ( http://www.php.net/manual/en/class.domdocument.php ), so you won't need to rebuild your HTML manually. 使用DOMDocument()库,您也可以在需要时立即写回结果( http://www.php.net/manual/en/class.domdocument.php ),因此您无需手动重建HTML 。 The library also allows you to write-back the manipulated HTML. 该库还允许您写回操作的HTML。

Good luck! 祝好运!

Maybe this will help you, I used preg_replace() with multiple patterns, I'm assuming that you trust the one who's creating the "HTML file": 也许这对您有帮助,我将preg_replace()与多种模式一起使用,我假设您信任创建“ HTML文件”的人:

$a = 5;
$b = 7;
$html = '<if condition="$a == $b">
    a is equal with b
<elseif condition="$a > $b">
    a is larger than b
<elseif condition="$a < $b">
    a is smaller than b
</if>';

$new_html = preg_replace(array('/<if condition="(.*)">\s*(.*)/', '/<elseif condition="(.*)">\s*(.*)/', '/<\/if>/'), array('if($1){'.PHP_EOL.'echo "$2";', '}elseif($1){'.PHP_EOL.'echo "$2";', '}'), $html);
eval($new_html); // result
var_dump($new_html); // This is to view the "final" code

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM