Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.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字符串控制台参数到数组_Php_Regex_Arrays_Preg Match_Explode - Fatal编程技术网

PHP字符串控制台参数到数组

PHP字符串控制台参数到数组,php,regex,arrays,preg-match,explode,Php,Regex,Arrays,Preg Match,Explode,我想知道如何将给定字符串转换为指定数组: 字符串 all ("hi there \(option\)", (this, that), other) another 需要结果(数组) 这是我在PHP上制作的一种控制台。 我试图使用preg\u match\u all但是,我不知道如何在括号中找到括号,以便“在数组中生成数组” 编辑 示例中未指定的所有其他字符应视为String 编辑2 我忘了提到括号外的所有参数都应该由空格字符检测。我想知道这是否有效: 将(替换为数组( 使用正则表达式在单词或括

我想知道如何将给定字符串转换为指定数组:

字符串

all ("hi there \(option\)", (this, that), other) another
需要结果(数组)

这是我在PHP上制作的一种控制台。 我试图使用
preg\u match\u all
但是,我不知道如何在括号中找到括号,以便“在数组中生成数组”

编辑

示例中未指定的所有其他字符应视为
String

编辑2


我忘了提到括号外的所有参数都应该由
空格
字符检测。

我想知道这是否有效:

  • 替换为
    数组(
  • 使用正则表达式在单词或括号后加逗号,不加逗号

    preg_replace('/[^,]\s+/',',',',$string)

  • eval(\$result=Array($string)”)


  • 我将给出实现此功能的算法或伪代码。希望您能够了解如何在PHP中实现它:

    function Parser([receives] input:string) returns Array
    
    define Array returnValue;
    
    for each integer i from 0 to length of input string do
        charachter = ith character from input string.
    
        if character is '('
            returnValue.Add(Parser(substring of input after i)); // recursive call
    
        else if character is '"'
            returnValue.Add(substring of input from i to the next '"')
    
        else if character is whitespace
            continue
    
        else
            returnValue.Add(substring of input from i to the next space or end of input)
    
       increment i to the index actually consumed
    
    
    return returnValue
    
    10000英尺概述 您需要使用一个小型的自定义解析器来实现这一点:代码获取此表单的输入,并将其转换为所需的表单

    在实践中,我发现将此类解析问题根据其复杂性分为以下三类非常有用:

  • 琐碎的:可以用几个循环和人性化的正则表达式解决的问题。这类问题很有诱惑力:如果你甚至有点不确定问题是否可以用这种方式解决,一个很好的经验法则是确定它不能解决
  • >强>易:需要自己构建一个小解析器的问题,但仍然很简单,把大炮放出来是不太有意义的。如果你需要写超过100行代码,那么就要考虑升级到下一个类别。
  • 所涉及的问题:对于这些问题,进行形式化处理并使用已经存在的、经过验证的解析器生成器是有意义的
  • 我将这个特殊问题归类为第二类,这意味着你可以这样处理它:

    编写一个小型解析器 定义语法 要做到这一点,您必须首先定义(至少是非正式地,通过一些简短的注释)要解析的语法。请记住,大多数语法都是在某个时刻递归定义的。因此,假设我们的语法是:

    • 输入是一个序列
    • 序列是一系列零个或多个标记
    • 标记可以是单词、字符串或数组
    • 标记由一个或多个空白字符分隔
    • 单词是一系列字母字符(A-z)
    • 字符串是包含在双引号内的任意字符序列
    • 数组是一系列由逗号分隔的一个或多个标记
    您可以看到,我们在一个地方有递归:序列可以包含数组,数组也可以根据序列定义(因此它可以包含更多数组等)

    像上面那样非正式地处理这个问题作为一个介绍比较容易,但是如果你这样做的话,关于语法的推理就容易多了

    构建lexer 掌握了语法后,您知道需要将输入分解为标记,以便进行处理。接受用户输入并将其转换为语法定义的单个片段的组件称为a。lexer是哑的;它们只关心“外观”不要试图检查输入是否有意义

    下面是我编写的一个简单的lexer,用于解析上述语法(不要将其用于任何重要的事情;可能包含bug):

    构建解析器 完成这项工作后,下一步是构建一个组件:一个检查词法输入并将其转换为所需格式的组件。解析器是智能的;在转换输入的过程中,它还确保输入符合语法规则

    解析器通常实现为(也称为有限状态机或有限自动机),工作方式如下:

    • 解析器有一个状态;这通常是一个适当范围内的数字,但每个状态也用一个更人性化的名称来描述
    • 有一个循环一次读取一个lexed标记。根据标记的当前状态和值,解析器可能决定执行以下一个或多个操作:
    • 采取一些影响其输出的措施
    • 将其状态更改为其他值
    • 确定输入格式错误并产生错误


    1解析器生成器是一种程序,它的输入是形式语法,输出是一个词法分析器和一个你可以“添加水”的解析器:只需扩展代码就可以执行“采取一些行动”根据令牌的类型,其他一切都已经处理好了。快速搜索这个主题就会得到led

    据我所知,括号问题是Chomsky语言类2,而正则表达式相当于Chomsky语言类3,因此不应该有正则表达式来解决这个问题m

    但我不久前读到一篇文章:

    此PCRE模式解决了括号问题(假设PCRE_扩展选项设置为忽略空白):
    \((((?>[^()]+)|(?R))*\)

    带分隔符但不带空格:
    /\((((?>[^()]+)|(?R))*\)/

    这是我的

    该手册中有一个示例,它解决了与您指定的问题几乎相同的问题! 你或其他人可能会发现它,并继续这个想法


    我认为最好的解决方案是用
    preg\u match\u all
    编写一个病态的递归模式。遗憾的是,我没有能力做这种疯狂的事情!

    如果你正在构建语法树,毫无疑问你应该编写解析器。但是如果你只需要解析这个示例输入
    regex
    ,还是有可能的
    function Parser([receives] input:string) returns Array
    
    define Array returnValue;
    
    for each integer i from 0 to length of input string do
        charachter = ith character from input string.
    
        if character is '('
            returnValue.Add(Parser(substring of input after i)); // recursive call
    
        else if character is '"'
            returnValue.Add(substring of input from i to the next '"')
    
        else if character is whitespace
            continue
    
        else
            returnValue.Add(substring of input from i to the next space or end of input)
    
       increment i to the index actually consumed
    
    
    return returnValue
    
    $input = 'all ("hi there", (this, that) , other) another';
    
    $tokens = array();
    $input = trim($input);
    while($input) {
        switch (substr($input, 0, 1)) {
            case '"':
                if (!preg_match('/^"([^"]*)"(.*)$/', $input, $matches)) {
                    die; // TODO: error: unterminated string
                }
    
                $tokens[] = array('string', $matches[1]);
                $input = $matches[2];
                break;
            case '(':
                $tokens[] = array('open', null);
                $input = substr($input, 1);
                break;
            case ')':
                $tokens[] = array('close', null);
                $input = substr($input, 1);
                break;
            case ',':
                $tokens[] = array('comma', null);
                $input = substr($input, 1);
                break;
            default:
                list($word, $input) = array_pad(
                    preg_split('/(?=[^a-zA-Z])/', $input, 2),
                    2,
                    null);
                $tokens[] = array('word', $word);
                break;
        }
        $input = trim($input);
    }
    
    print_r($tokens);
    
    <?php
    $str = 'all, ("hi there", (these, that) , other), another';
    
    $str = preg_replace('/\, /', ',', $str); //get rid off extra spaces
    /*
     * get rid off undefined constants with surrounding them with quotes
    */
    $str = preg_replace('/(\w+),/', '\'$1\',', $str);
    $str = preg_replace('/(\w+)\)/', '\'$1\')', $str);
    $str = preg_replace('/,(\w+)/', ',\'$1\'', $str);
    
    $str = str_replace('(', 'array(', $str);
    
    $str = 'array('.$str.');';
    
    echo '<pre>';
    eval('$res = '.$str); //eval is evil.
    print_r($res); //print the result
    
    $ar = explode('("', $st);
    
    $ar[1] = explode('",', $ar[1]);
    
    $ar[1][1] = explode(',', $ar[1][1]);
    
    $ar[1][2] = explode(')',$ar[1][1][2]);
    
    unset($ar[1][1][2]);
    
    $ar[2] =$ar[1][2][1];
    
    unset($ar[1][2][1]);
    
    $str=transformEnd(transformStart($string));
    $str = preg_replace('/([^\\\])\(/', '$1array(', $str);
    $str = 'array('.$str.');';
    eval('$res = '.$str);
    print_r($res); //print the result
    
    function transformStart($str){
        $match=preg_match('/(^\(|[^\\\]\()/', $str, $positions, PREG_OFFSET_CAPTURE);
        if (count($positions[0]))
            $first=($positions[0][1]+1);
        if ($first>1){
            $start=substr($str, 0,$first);
            preg_match_all("/(?:(?:\"(?:\\\\\"|[^\"])+\")|(?:'(?:\\\'|[^'])+')|(?:(?:[^\s^\,^\"^\']+)))/is",$start,$results);
            if (count($results[0])){
                $start=implode(",", $results[0]).",";
            } else {
                $start="";
            }
            $temp=substr($str, $first);
            $str=$start.$temp;
        }
        return $str;
    }
    
    function transformEnd($str){
        $match=preg_match('/(^\)|[^\\\]\))/', $str, $positions, PREG_OFFSET_CAPTURE);
        if (($total=count($positions)) && count($positions[$total-1]))
            $last=($positions[$total-1][1]+1);
        if ($last==null)
            $last=-1;
        if ($last<strlen($str)-1){
            $end=substr($str,$last+1);
            preg_match_all("/(?:(?:\"(?:\\\\\"|[^\"])+\")|(?:'(?:\\\'|[^'])+')|(?:(?:[^\s^\,^\"^\']+)))/is",$end,$results);
            if (count($results[0])){
                $end=",".implode(",", $results[0]);
            } else {
                $end="";
            }
            $temp=substr($str, 0,$last+1);
            $str=$temp.$end;
        }
        if ($last==-1){
            $str=substr($str, 1);
        }
        return $str;
    }