【问题标题】:preg_match - Regular Expression To Create Arraypreg_match - 创建数组的正则表达式
【发布时间】:2015-06-02 19:21:05
【问题描述】:

我的数据 -

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

【问题讨论】:

    标签: php arrays regex preg-match


    【解决方案1】:

    你的正则表达式没有意义,因为你有它。一方面,您缺少分隔符。 {}. 都是特殊的正则表达式字符,因此它们应该被转义。这也看起来像一个 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

    我稍后会写一下这里使用的部分。如果您有特殊问题,请发布。

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

    ~ 是分隔符,它告诉正则表达式引擎表达式从哪里开始。外部的m 是一个修饰符,告诉它将每一行视为一个字符串。 ^$ 告诉它匹配“字符串”的开头和结尾,在这种情况下,每一行都是因为 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 相同)。然后在最后一行,我们为全局变量分配新值。

    【讨论】:

    • 我的正则表达式完全没问题 - 兄弟。无论如何,意思是 - 你的输出与请求不匹配。
    • 什么@Falt4rm?!我对您的正则表达式/答案只字未提。我回答时你的回答没有建立数组。
    • 哦,哈哈,好吧,我认为你谈到了我的模式——我认为他的模式是为了填补空白,而不是真正的模式。 mb 然后。对此我深表歉意。
    【解决方案2】:

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

    说明:

    • (\'.*?\') - 第 1 组:匹配任意数量的字符 BETWEEN char ''' (lazy)
    • :\s?\{'.*? - 后跟 ':' 和 O 或 1 个 espace 字符和 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
                )
    
        )
    
    )
    

    【讨论】:

      【解决方案3】:

      看起来它已经在 J​​SON 中了,所以您可以使用 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)
        }
      }
      */
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-05
        • 2014-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-02
        • 2013-04-05
        相关资源
        最近更新 更多