preg_match - 正则表达式创建数组

时间:2015-06-02 19:21:06

标签: php arrays regex preg-match

我的数据 -

{'/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的情况下将其转换为数组?

3 个答案:

答案 0 :(得分:3)

你的正则表达没有意义。首先,你缺少分隔符。 {}.都是特殊的正则表达式字符,因此应对其进行转义。这看起来也像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
        )

)

以下是我使用的功能/修饰符信息的链接。

  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
  4. 我会稍微写下这里使用的部件。如果您有特殊问题,请发布。

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

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

答案 1 :(得分:1)

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

说明:

  • (\'.*?\') - 第1组:匹配任何数量的字符在char&#39;&#39;&#39;&#39; (懒惰)
  • :\s?\{'.*? - 跟随&#39;:&#39;和O或1个espace字符和char&#39; {&#39;和任何数量的任何字符(懒惰)
  • (\d{1,})\} - 第2组:至少1位数,然后是&#39;}&#39;

请参阅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>";
?>

OUPUT:

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
            )

    )

)

答案 2 :(得分:1)

看起来它已经在JSON中了,所以你可以使用ManyToManyRelationshipMetadata把它变成对象。要使它与PHP的json_decode()兼容,您需要做的只是将单个刻度转换为双引号。

json_decode()