gpt4 book ai didi

php - 在 PHP 中解析命令参数

转载 作者:IT王子 更新时间:2023-10-29 00:15:35 24 4
gpt4 key购买 nike

是否有原生的“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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com