preg_match - 创建数组的正则表达式

preg_match - Regular Expression To Create Array

我的数据-

{'/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}}
{'/Users/aaron/.vim/autoload/timetap.vim': {'total': 0}}
{'/Users/aaron/.vimrc': {'total': 5}}
{'/Users/aaron/Documents/Programming/PHP/TimeTapCLI/composer.json': {'total': 144}}
{'/Users/aaron/Documents/Programming/PHP/TimeTapCLI/timetap.php': {'total': 351}}
{'/Users/aaron/Box/linux/.vim/autoload/timetap.vim': {'total': 37}}
{'/Users/aaron/Box/cats.tex': {'total': 184}}

我正在尝试创建一个正则表达式,以便我可以使用 preg_match 将上面的内容转换为数组。我希望数据看起来像 -

我想要一个包含所有数据的数组所以我认为它应该如下所示-

 array (
   [0] => array (
      [0] => '/Users/aaron/Box/cats.tex'
      [1] => array (
                  [total] =>'184'
             )
   }
 }

我的尝试 preg_match -

$subject = file_get_contents('/Users/aaron/.timetap/full.db');
$pattern = '{...}';
preg_match($pattern, substr($subject,3), $matches, PREG_OFFSET_CAPTURE);

为了获取上述数据并将其转换为 PHP 中的数组,模式应该是什么?是否有 PHP 函数可以在不使用 preg_match 的情况下将其转换为数组?

我使用这个模式匹配了两个目标:/(\'.*?\'):\s?\{'.*?(\d{1,})\}/

解释:

  • (\'.*?\') - 第 1 组:匹配任意数量的字符 BETWEEN char '''(惰性)
  • :\s?\{'.*? - 后跟 ':' 和 O 或 1 个空格字符和 char '{' 以及任意数量的任意字符(惰性)
  • (\d{1,})\} - 第 2 组:至少 1 个数字,然后是 '}'

Demo

<?php
$array_input = 
     array( 0 => "{'/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}}", 
            1 => "{'/Users/aaron/.vim/autoload/timetap.vim': {'total': 0}}");

$pattern = "/(?:(\'.*?\'):\s?\{'.*?(\d{1,})\})/";
$array_output = array();

for($i = 0; $i < count($array_input); ++$i)
{
    preg_match($pattern, $array_input[$i], $output);
    $array_output[$i][0] = $output[1];
    $array_output[$i][1] = array('total' => ($output[2]));
}

print "<pre>";
print_r($array_output);
print "<pre>";
?>

输出:

Array
(
[0] => Array
    (
        [0] => '/Users/aaron/Applications/developer-vagrant/web/g.php'
        [1] => Array
            (
                [total] => 22
            )

    )

[1] => Array
    (
        [0] => '/Users/aaron/.vim/autoload/timetap.vim'
        [1] => Array
            (
                [total] => 0
            )

    )

)

你的正则表达式没有意义。一方面,您缺少定界符。 {}. 都是特殊的正则表达式字符,因此应该对它们进行转义。这看起来也像一个 JSON 数据结构,因此 JSON 函数可能对您有用。如果您仍想使用 REGEX,假设您的数据结构是一致的,我会这样做。

<?php
$string = "{'/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}}
{'/Users/aaron/.vim/autoload/timetap.vim': {'total': 0}}
{'/Users/aaron/.vimrc': {'total': 5}}
{'/Users/aaron/Documents/Programming/PHP/TimeTapCLI/composer.json': {'total': 144}}
{'/Users/aaron/Documents/Programming/PHP/TimeTapCLI/timetap.php': {'total': 351}}
{'/Users/aaron/Box/linux/.vim/autoload/timetap.vim': {'total': 37}}
{'/Users/aaron/Box/cats.tex': {'total': 184}}";
$pattern = '~^\{(.*)\}$~m';
$data[] = preg_replace_callback($pattern, function($matches) {
    global $output_data;
    preg_match("~'(.*?)'\s*:\s*\{'(.*?)'\s*:\s*(\d+)\}~", $matches[1], $output);
    $output_data[$output[1]] = array($output[2] => $output[3]);
}, $string);
print_r($output_data);

输出:

Array
(
    [/Users/aaron/Applications/developer-vagrant/web/g.php] => Array
        (
            [total] => 22
        )

    [/Users/aaron/.vim/autoload/timetap.vim] => Array
        (
            [total] => 0
        )

    [/Users/aaron/.vimrc] => Array
        (
            [total] => 5
        )

    [/Users/aaron/Documents/Programming/PHP/TimeTapCLI/composer.json] => Array
        (
            [total] => 144
        )

    [/Users/aaron/Documents/Programming/PHP/TimeTapCLI/timetap.php] => Array
        (
            [total] => 351
        )

    [/Users/aaron/Box/linux/.vim/autoload/timetap.vim] => Array
        (
            [total] => 37
        )

    [/Users/aaron/Box/cats.tex] => Array
        (
            [total] => 184
        )

)

这里是关于我用过的 functions/modifiers 的信息的链接。

  1. http://php.net/manual/en/reference.pcre.pattern.modifiers.php
  2. http://php.net/manual/en/function.preg-replace-callback.php
  3. http://php.net/manual/en/function.preg-match.php

我稍后会把这里用到的部分写下来。如果您有特殊问题,请 post.

对正在发生的事情的解释...

~ 是分隔符,它告诉正则表达式引擎表达式从哪里开始到哪里结束。外面的 m 是一个修饰符,它告诉它将每一行都视为一个字符串。 ^$ 告诉它匹配 "string" 的开始和结束,在这种情况下,每一行都是因为 m 修饰符。 { 之前的 \ 是为了转义在正则表达式中具有特殊上下文的大括号。 . 是任意字符,* 是量词,表示出现零次或多次。当这些配对在一起时,它意味着零个或多个任何字符。围绕它的 () 是一个捕获组,用于存储其中的内容,而 \} 是我们停止最后一个大括号的地方。所以从 {'/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}} 我们最终得到 '/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}。我们将它传递给一个函数,因为我们想进一步过滤它。我们在这里使用 global 是因为我们在这个匿名函数内部,并希望在我们 done.The '(.*?)' 搜索单引号之间的所有内容时可以访问它。这被称为 lazy/non 贪心,? 使其在第一次出现下一个字符(单引号)时停止。 \s* 是任意数量的空格。此处正则表达式的其余部分应该可以从前面的描述中解读出来。 $matches[1] 是因为我们想首先对 preg_replace_callback 中的值进行分组,$matches[0] 是找到的所有内容(与 preg_match 相同)。然后在最后一行,我们为全局变量分配新值。

看起来它已经在 JSON 中了,因此您可以使用 json_decode() 将其转换为对象。要使其与 PHP 的 json_decode() 兼容,您需要做的就是将单引号变成双引号。

$string = "{'/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}}";
$string = str_replace("'", '"', $string);
$object = json_decode($string);
var_dump($object);
/*
Outputs the following:
object(stdClass)#1 (1) {
  ["/Users/aaron/Applications/developer-vagrant/web/g.php"]=>
  object(stdClass)#2 (1) {
    ["total"]=>
    int(22)
  }
}
*/