preg_match - 正则表达式创建数组

preg_match  - 正则表达式创建数组

问题描述:

My data -

{'/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}}

I am attempting to create a regular expression so I can convert the above into an array using preg_match. I want the data to look like -

I want an array of all of the data So I believe it should look like below-

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

My attempt at preg_match -

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

What would the pattern be in order to take the above data and turn it into an array in PHP? Is there a PHP function that could convert this into an Array without using preg_match?

我的数据 - p>

  {'/ 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}} \  n {'/ 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}} 
  code>  pre> 
 
 

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

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

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

我尝试preg_match - p>

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

为了获取上述数据并将其转换为PHP中的数组,该模式将是什么?是否有一个PHP函数可以将其转换为 不使用preg_match的数组? p> div>

You're regex doesn't make sense as you have it. For one thing you are missing delimiters. The {, }, and . are all special regex characters so they should be escaped. This also looks like a JSON data structure so the JSON functions might be of use to you. If you still want to go REGEX here's how I'd do it presuming your data structure is consistent.

<?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);

Output:

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
        )

)

Here are links to the information on the functions/modifiers I've used.

  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

I'll do a write up of the parts used here in a bit. If you have particular questions please post.

Explanation of what is happening...

The ~ are delimiters which tell the regex engine where the expression starts at ends. The m on the outside is a modifier which tells it to treat each line as a as a string. The ^ and $ tell it to match to start and end of a "string", in this case each line because of the m modifier. The \ before the { is to escape the curly brace which has a special context in regex. The . is any character and the * is a quantifier meaning zero or more occurrences. When these are paired together it means zero or more of any characters. The () around this are a capturing group which stores what is inside it, and the \} is so we stop a the last curly brace. So from {'/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}} we end up with '/Users/aaron/Applications/developer-vagrant/web/g.php': {'total': 22}. We pass this into a function because we want to filter this down further. We use the global here because we are inside of this anonymous function and want it to be accessible when we are done.The '(.*?)' is searching for everything between the single quotes. This is known as a lazy/non greedy, the ? makes it stop at the first occurrence of the next character (the single quote). The \s* are any amount of whitespace. The rest of the regex here should be decipherable from the previous descriptions. The $matches[1] is because we want to first grouped value from the preg_replace_callback the $matches[0] is everything that was found (same with preg_match). Then on the final line we assign our global variable the new value.

I matched both targets using this pattern : /(\'.*?\'):\s?\{'.*?(\d{1,})\}/

Explanation :

  • (\'.*?\') - Group 1 : Match any amount of characteres BETWEEN char ''' (lazy)
  • :\s?\{'.*? - Followed by ':' and O or 1 espace character and char '{' and any amount of any characters (lazy)
  • (\d{1,})\} - Group 2 : 1digits at least and followed by '}'

See 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
            )

    )

)

That looks like it's already in JSON, so you could just use json_decode() to turn it into objects. All you need to do to make it compatible with PHP's json_decode() is turn the single ticks into double quotes.

$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)
  }
}
*/