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 的信息的链接。
- http://php.net/manual/en/reference.pcre.pattern.modifiers.php
- http://php.net/manual/en/function.preg-replace-callback.php
- 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)
}
}
*/
我的数据-
{'/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 的信息的链接。
- http://php.net/manual/en/reference.pcre.pattern.modifiers.php
- http://php.net/manual/en/function.preg-replace-callback.php
- 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)
}
}
*/