php - 在 PHP 中解析命令参数

标签 php parsing command-line-arguments

是否有原生的“PHP 方式”来解析来自 string 的命令参数?例如,给定以下 string:

foo "bar \"baz\"" '\'quux\''

我想创建以下数组:

array(3) {
  [0] =>
  string(3) "foo"
  [1] =>
  string(7) "bar "baz""
  [2] =>
  string(6) "'quux'"
}

我已经尝试利用 token_get_all() , 但 PHP 的变量插值语法(例如 "foo ${bar} baz")几乎让我大吃一惊。

我很清楚我可以编写自己的解析器。命令参数语法非常简单,但如果有现有的本地方法来执行此操作,我更愿意使用它而不是自己动手。

编辑:请注意,我希望从 string 中解析参数,而不是从 shell/命令行中解析。


编辑 #2:下面是一个更全面的参数预期输入 -> 输出示例:

foo -> foo
"foo" -> foo
'foo' -> foo
"foo'foo" -> foo'foo
'foo"foo' -> foo"foo
"foo\"foo" -> foo"foo
'foo\'foo' -> foo'foo
"foo\foo" -> foo\foo
"foo\\foo" -> foo\foo
"foo foo" -> foo foo
'foo foo' -> foo foo

最佳答案

正则表达式非常强大:(?s)(?<!\\)("|')(?:[^\\]|\\.)*?\1|\S+ .那么这个表达式是什么意思?

  • (?s) : 设置 s用点匹配换行符 .
  • (?<!\\) : negative lookbehind,检查下一个标记前是否没有反斜杠
  • ("|') : 匹配单引号或双引号并将其放入第 1 组
  • (?:[^\\]|\\.)*? : 匹配除\以外的所有内容,或将\与紧随其后的(转义)字符匹配
  • \1 : 匹配第一组匹配的内容
  • | : 或
  • \S+ : 匹配除空格以外的任何内容一次或多次。

我们的想法是捕捉一个引语并将其分组以记住它是单引号还是双引号。负面回顾是为了确保我们不匹配转义引号。 \1用于匹配第二对引号。最后我们使用交替来匹配任何不是空格的东西。这个解决方案很方便,几乎适用于任何支持回顾和反向引用的语言/风格。当然,此解决方案期望报价已关闭。结果在第 0 组中找到。

让我们用 PHP 来实现它:

$string = <<<INPUT
foo "bar \"baz\"" '\'quux\''
'foo"bar' "baz'boz"
hello "regex

world\""
"escaped escape\\\\"
INPUT;

preg_match_all('#(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $matches);
print_r($matches[0]);

如果您想知道我为什么使用 4 个反斜杠。那就看看我的previous answer .

输出

Array
(
    [0] => foo
    [1] => "bar \"baz\""
    [2] => '\'quux\''
    [3] => 'foo"bar'
    [4] => "baz'boz"
    [5] => hello
    [6] => "regex

world\""
    [7] => "escaped escape\\"
)

<知识库> Online regex demo <知识库> Online php demo


删除引号

使用命名组和一个简单的循环非常简单:

preg_match_all('#(?<!\\\\)("|\')(?<escaped>(?:[^\\\\]|\\\\.)*?)\1|(?<unescaped>\S+)#s', $string, $matches, PREG_SET_ORDER);

$results = array();
foreach($matches as $array){
   if(!empty($array['escaped'])){
      $results[] = $array['escaped'];
   }else{
      $results[] = $array['unescaped'];
   }
}
print_r($results);

Online php demo

关于php - 在 PHP 中解析命令参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17848618/

相关文章:

php - 将excel文件导入PHP并存储在MySQL中时如何使用PHPExcel库读取下标/上标/换行

php - 如何正确放置我的字幕?

php - MySQL 返回 MIN id 而不是 MAX id?

c - 使用 sscanf 解析不会保留数组以供后续使用

xml - 使用 XML::Parser 解析大型 XML 文件时如何查看进度?

jquery - 通过浏览器扩展添加表值

c++ - 如何使用 linux 命令传递输入和配置文件

r - 如何在命令提示符下获取用户输入并将其传递给 R

php - 通过互联网IP地址从一台计算机访问xampp到另一台计算机

用于解析参数的 bash 工具