(PHP)Parse命令

(PHP)Parse命令,php,arrays,parsing,Php,Arrays,Parsing,我想获取命令标记(get、FROM、IN等)的值。我的命令是: // My command $_cmd = 'GET a, b FROM p IN a and c="I am from Sarajevo" or d>1 '; // My parser if(preg_match_all('/(GET|FROM|IN)\s+([^\s]+)/si',$_cmd, $m)) $cmd = array_combine($m[1], $m[2]); 输出: Array ( [GET

我想获取命令标记(get、FROM、IN等)的值。我的命令是:

// My command
$_cmd = 'GET a, b FROM p IN a and c="I am from Sarajevo" or d>1 ';

// My parser
if(preg_match_all('/(GET|FROM|IN)\s+([^\s]+)/si',$_cmd, $m))
    $cmd = array_combine($m[1], $m[2]);
输出:

Array
(
  [GET] => a,
  [FROM] => p
  [IN] => a
  [from] => Sarajevo"
)
我正在寻找以下输出:

Array
(
  [GET] => a, b
  [FROM] => p
  [IN] => a and c="I am from Sarajevo" or d>1
)

如您所见,问题在于字符串中的空格重复命令标记(如
中的
)。那么如何解析这个命令呢?

您需要为此开发一种脚本语言。regexp不适用于这些目的。

您可以删除分隔符
/
后不区分大小写的
i
。还要确保关键字后面至少有一个空格

if( preg_match_all('/(GET|FROM|IN)(.(?!(GET|FROM|IN)))+\s*/si',$_cmd, $m))

这意味着-在关键字后面找到任何没有跟GET的char,FROM或后面有空格的char

您无法用单个正则表达式轻松解析它。(这是可行的,但并不简单。)

您应该使用一个简单的标记器,其中正则表达式再次成为一个有用的工具:

  preg_match_all('/\w+|".*?"|\W/', $_cmd = 'GET a, b FROM p IN a and c="I am from Sarajevo" or d>1 ', $list);
这提供了一个简单的列表,您只需找到感兴趣的子句,然后重新合并后续标记(尽管我对您的用例感到困惑):


如果跳过
/i
-修饰符会怎么样?难道你不能确保只从
中计算
,而不是从
中计算
?是否会出现这样一种情况,即
中的
将包含一个带有大写的
from
的字符串?我想这与SQL有关。。。只需使用SQL,不要尝试为此开发接口。@Dor-请不要建议SQL解析器。我需要为我的ORM项目解析它。@dino beytar:“对象关系映射(ORM)系统(以及使用它们的“框架”)是另一个常见的性能噩梦。”,摘自《高性能MySQL》,第二本Edition@Dor-是的,你说得对。但我认为,这个命令行可以帮助我实现项目的标准化。因此,我想,我将得到较少的麻烦升级。我只是想试试这个方法。也许我完全走错了路。如果从a中的p得到a,b和c=“我来自萨拉热窝”或d>1会怎么样?但是GET后面跟着FROM?!我知道这个主意,但它行得通吗。。。FROM-有相交我在每个项目后面都有空格。你能再检查一下你的密码吗?我错了吗?您可以使用
(?!\s)\W
代替
\W
来删除空格。如果要合并生成的零件,则应保留空格。(这就是我再次禁用该选项的原因。)--这取决于您是需要它作为标记器,还是只需要分解字符串部分;但那只是更多的工作。(字符串函数和大量PHP代码通常比preg_match慢。)那么不使用Regex的解决方案是什么呢?@dino beytar:您可以使用Regex,但这绝对不是解决方案的主要部分。你需要开发(或使用可用的自由/开源软件)一个解释器:你的意思是,我应该开发或使用一个不使用PHP的解释器,还是我已经在尝试开发一个解释器?@dino beytar:我想你已经尝试使用正则表达式开发一个解释器,我告诉过你这不是开发解释器的方法。但我也认为,您应该避免尝试开发或使用解释器,因为这将是一场性能噩梦。我觉得你的代码有问题吗?我错了吗?是的,我错过了引号内的“表单”,我没有PHP框。
[0] => Array
    (
        [0] => GET
        [1] => a
        [2] => ,
        [3] => b
        [4] => FROM
        [5] => p
        [6] => IN
        [7] => a
        [8] => and
        [9] => c
        [10] => =
        [11] => "I am from Sarajevo"
        [12] => or
        [13] => d
        [14] => >
        [15] => 1
    )
$_cmd = 'GET a, b FROM p IN a and c="I am from Sarajevo" or d>1 ';
$tpar = preg_split('/\s+(GET|FROM|IN)\s+/i', ' '.$_cmd.' ', -1, PREG_SPLIT_DELIM_CAPTURE);
array_walk($tpar, 'trim');

print_r($tpar);

// gives:
array(
  [0] => GET
  [1] => a, b
  [2] => FROM
  [3] => p
  [4] => IN
  [5] => a and c="I am from Sarajevo" or d>1
)
// the rest is straight forward