如何使用引号解析PHP中的控制台命令字符串

时间:2011-12-09 10:17:36

标签: php

对于我的游戏,我正在编写一个控制台,通过AJAX发送消息,然后从服务器接收输出。

例如,输入为:

/testmessage Hello!

但是,我还需要解析引号,例如:

/testmessage "Hello World!"

但是,由于我只是用空格爆炸字符串,PHP将"HelloWorld!"视为单独的参数。如何让PHP认为“Hello World!”是一个参数? 现在我正在使用以下代码来解析命令:

// Suppose $inputstring = '/testmessage "Hello World!"';
$inputstring = substr($inputstring, 1);

$parameters = explode(" ", $inputstring);

$command = strtolower($parameters[0]);

switch ($command) {
    case "testmessage":
        ConsoleDie($parameters[1]);
        break; 
}

提前谢谢。

4 个答案:

答案 0 :(得分:2)

此代码将执行您想要的操作:

  $params = preg_split('/(".*?")/', '/testmessage "Hello World!" 1 2 3', -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
  $realParams = array();
  foreach($params as $param)
  {
     $param = trim($param);
     if ($param == '')
        continue;

     if (strpos($param, '"') === 0)
        $realParams = array_merge($realParams, array(trim($param, '"')));
     else
        $realParams = array_merge($realParams, explode(' ', $param));
  }
  unset($params);
  print_r($realParams);
打印:

array(5) {
  [0]=>
  string(12) "/testmessage"
  [1]=>
  string(14) "Hello World!"
  [2]=>
  string(1) "1"
  [3]=>
  string(1) "2"
  [4]=>
  string(1) "3"
}

注意:正如您所看到的,第一个参数是命令

答案 1 :(得分:2)

希望这段代码更“易懂”

$input = $inputstring = '/testmessage "Hello World!" "single phrase" level two';

// find the parameters surrounded with quotes, grab only the value (remove "s)
preg_match_all('/"(.*?)"/', $inputstring, $quotes);

// for each parameters with quotes, put a 'placeholder' like {{1}}, {{2}}
foreach ($quotes[1] as $key => $value) {
  $inputstring = str_replace($value, "{{{$key}}}", $inputstring);
}

// then separate by space
$parameters = explode(" ", $inputstring);

// replace the placeholders {{1}} with the original value
foreach ($parameters as $key => $value) {
  if (preg_match('{{(\d+)}}', $value, $matches)) {
    $parameters[$key] = $quotes[1][$matches[1]];
  }
}

// here you go
print_r($parameters);

答案 2 :(得分:0)

我可能没有完全理解你,但如果你假设第一个单词总是一个命令词,并且后面的任何内容都是'一个参数'你可以做以下

$inputstring = substr($inputstring, 1);

$parameters = explode(" ", $inputstring);

// shift the first element off the array i.e. the command
$command = strtolower(array_shift($parameters));

// Glue the rest of the array together
$input_message = implode($parameters);

switch ($command) {
    case "testmessage":
    ConsoleDie($input_message);
    break; 
}

答案 3 :(得分:0)

您可以使用Symfony Console Component提供安全,干净的方式来获取控制台输入。

对于您的用例,您应该:

use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;

$input = new ArgvInput(null, new InputDefinition(array(
    new InputArgument('message', InputArgument::REQUIRED)
)));

$parameters = $input->getArguments(); // $parameters['message'] contains the first argument