PHP preg_match 返回字符串的字符数而不是预期结果

PHP preg_match returning character count of string instead of expected result

我正在尝试搜索 shell 脚本中定义的变量。

<?php
$code = '
#!/bin/bash
foo = "Hello world!"
bar="123"
echo -e "The value of foo is $foo\n"
echo -e "The value of bar is $bar"
';
$var_pattern = "/(^[a-zA-Z0-9_]+[\= ]+([\"\']?)+(.)+([\"\']?))*$/";
preg_match($var_pattern, $code, $matches, PREG_OFFSET_CAPTURE);
print_r($matches);

上面的例子中定义了两个变量(foo & bar)。我使用 regex101.com.

检查的正则表达式

我得到的结果是...

Array
(
    [0] => Array
        (
            [0] => 
            [1] => 121
        )

)

121 似乎是代码中的字符数。我期待的结果更像是...

Array
(
    [0] => Array
        (
            [0] => 
            [1] => foo = "Hello world!"
        ),
    [1] => Array
        (
            [0] =>
            [1] => bar="123"
        )
)

或类似!我做错了什么?

您最初的方法有几个问题:

  • 缺少 /m 多行标志,因此 ^$ 没有锚线。
  • 外部 (…)* 捕获组已完全可选化 *
  • (.)+ 只会捕获包含值的一个字母。
  • 并且 PREG_OFFSET_CAPTURE 是多余的,除非你真的想要匹配位置。

由于这或多或少是一种经典的 ini 样式格式,您可以简单地使用:

                     key                  value        multiline
                      ↑                     ↑             ↑
 preg_match_all("/^ (\w+) \s*=\s* [\"\']? (.+?) [\"\']? $/mix", $str, $m);
                             ↓       ↓             ↓
                           equal   quote         quote

然后你甚至可以从 $m 匹配数组重建一个关联键→值数组, =array_combine($m[1], $m[2]).

尝试以下模式:

/([a-zA-Z][a-zA-Z0-9_]*)\s*=\s*(|['"])(.+)/g

工作示例@regex101