(PHP)Parse命令
我想获取命令标记(get、FROM、IN等)的值。我的命令是:(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
// 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