Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP正则表达式捕获模板标记和if语句标记_Php_Regex - Fatal编程技术网

PHP正则表达式捕获模板标记和if语句标记

PHP正则表达式捕获模板标记和if语句标记,php,regex,Php,Regex,我在html文件中有这样的标签,放在整个文件中 *|SUBJECT|* *|SUBJECT|* *|IFNOT:ARCHIVE_PAGE|* *|ARCHIVE|* *|END:IF|* *|FACEBOOK:PROFILEURL|* *|TWITTER:PROFILEURL|* *|FORWARD|* *|IF:REWARDS* *|REWARDS|* *|END:IF|* 使用这个PHP函数和正则表达式,我可以得到所有标记的结果 preg_match_all("/\*\|(

我在html文件中有这样的标签,放在整个文件中

*|SUBJECT|*
*|SUBJECT|*
*|IFNOT:ARCHIVE_PAGE|*
    *|ARCHIVE|*
*|END:IF|*
*|FACEBOOK:PROFILEURL|*
*|TWITTER:PROFILEURL|*
*|FORWARD|*
*|IF:REWARDS*
    *|REWARDS|*
*|END:IF|*
使用这个PHP函数和正则表达式,我可以得到所有标记的结果

preg_match_all("/\*\|(.*?)\|\*/", $this->template, $elements);
    $this->elements["Tags"] = $elements[0];
    $this->elements["TagNames"] = $elements[1];
我想要的是找到一种方法来捕获IF:(TAG)语句和IFNOT:(TAG)语句以及内容

到目前为止,我得到的是

ergex=> /\*\|IF(([A-Z{0-3}]):([A-Z_]+))\|\*(.*?)\*\|END:IF\|\*|\*\|(.*?)\|\*/g

但是它只捕捉到标签本身,作为一个整体,任何人都可以为我指出正确的方向或帮助我。

正如我在评论中提到的那样,你的方法过于简单,我可以让你开始使用我用于这些事情的方法。它更像是一种标记器/词法分析器/解析器方法

这听起来既大又可怕,但实际上让事情变得更简单了

<?php
function parse($subject, $tokens)
{
    $types = array_keys($tokens);
    $patterns = [];
    $lexer_stream = [];
    $result = false;
    foreach ($tokens as $k=>$v){
        $patterns[] = "(?P<$k>$v)";
    }
    $pattern = "/".implode('|', $patterns)."/i";
    if (preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE)) {
        //print_r($matches);
        foreach ($matches[0] as $key => $value) {
            $match = [];
            foreach ($types as $type) {
                $match = $matches[$type][$key];
                if (is_array($match) && $match[1] != -1) {
                    break;
                }
            }
            $tok  = [
                'content' => $match[0],
                'type' => $type,
                'offset' => $match[1]
            ];
            $lexer_stream[] = $tok;
        }
        $result = parseTokens( $lexer_stream );
    }
    return $result;
}

function parseTokens( array &$lexer_stream ){
    $result = [];
    $mode = 'none';
    while($current = current($lexer_stream)){
        $content = $current['content'];
        $type = $current['type'];
        switch($type){
            case 'T_WHITESPACE':
                next($lexer_stream);
            break;
            case 'T_TAG_START': 
                $mode = 'start';
                next($lexer_stream);
            break;
            case 'T_WORD': 
                if($mode == 'start') echo "Tag $content\n";
                if($mode == 'ifnot') echo "IfNot $content\n";
                next($lexer_stream);
            break;
            case 'T_TAG_END': 
                $mode = 'none';
                next($lexer_stream);
            break;
            case 'T_IFNOT':
                $mode = 'ifnot';
                next($lexer_stream);
            break;

            case 'T_EOF': return;

            case 'T_UNKNOWN':
            default:
                print_r($current);
                trigger_error("Unknown token $type value $content", E_USER_ERROR);
        }
    }
    if( !$current ) return;
    print_r($current);
    trigger_error("Unclosed item $mode for $type value $content", E_USER_ERROR);
}

$subject = '*|SUBJECT|*
*|SUBJECT|*
*|IFNOT:ARCHIVE_PAGE|*
    *|ARCHIVE|*
*|END:IF|*
*|FACEBOOK:PROFILEURL|*
*|TWITTER:PROFILEURL|*
*|FORWARD|*
*|IF:REWARDS*
    *|REWARDS|*
*|END:IF|*';

$tokens = [
    'T_WHITESPACE'      => '[\r\n\s\t]+',
    'T_TAG_START'       => '\*\|',
    'T_TAG_END'         => '\|\*',
    'T_IF'              => 'IF:',
    'T_IFNOT'           => 'IFNOT:',    
    'T_ENDIF'           => 'END:IF',
    'T_WORD'            => '\w+',
    'T_EOF'             => '\Z',
    'T_UNKNOWN'         => '.+?'
];

parse($subject,$tokens);
而不是我所拥有的,但它可能必须在:

    'T_TAG_START'       => '\*\|',
因为该标记将首先匹配它

也别忘了把
放在下一个($lexer\u stream)否则它将是一个无限循环。在嵌套结构(如数组)中,有必要使用while和next来控制数组指针


祝你好运,快乐

这是什么来源?你的第一个正则表达式已经捕获了普通和IF“模板标签”。匹配嵌套组对处理没有必要的帮助。而是按顺序循环所有结果,然后应用逻辑。-还有,是的,你是如何得到这样一个模板化的迷你语言的?编写您自己的标记器和解释器是一种毫无意义的结束方式(即查看调查的当前状态)。您使用的基本方法过于“简单化”,您应该采用标记方法。您可以参考这个基本的lexer/parser,这是我的灵感来源,我在另一个问题上使用它作为JSON对象解析器,版本如下:
    'T_IFNOT'           => '\*\|IFNOT:',
    'T_TAG_START'       => '\*\|',