进入 php 正则表达式中的父块内部
Get inside of parent blocks in php regex
你好,我有 2 个父(或更多...)块和其中的许多子块。
Block1 {
blockchild1 {
}
blockchild2 {
}
, ...
}
Block2 {
blockchild1 {
}
blockchild2 {
}
, ...
}
我想使用 php 正则表达式并首先获取
中的所有父块
([a-z-0-9]*)\s*[{](.*?)[}]
但是这个正则表达式在到达第一个子块关闭时停止 }
意味着第一个数据接收是
Block1 {
blockchild1 {
}
但我想得到这样的东西
array 1 = Block1
array 2 = blockchild1 {
}
blockchild2 {
}
, ...
我希望正则表达式传递子块 [}]
并获取父块内的所有内容。我的正则表达式是 PCRE (PHP)
试试这个:
$str = 'Block1 {
block1child1 {
}
block1child2 {
}
block1child3 {
}
}
Block2 {
block2child1 {
}
block2child2 {
}
}';
$sub = '(\s*[a-z-0-9]*\s*{.*?}\s*)*';
preg_match_all("/([a-z-0-9]*)\s*{($sub)}/sim", $str, $matches, PREG_SET_ORDER);
var_dump($matches);
我使用变量 $sub
来阐明方法。它returns:
$matches[0][1] = 'Block1';
$matches[0][2] = '
block1child1 {
}
block1child2 {
}
block1child3 {
}
';
它包含 Block2 的正确输出($matches
的索引 1
)。
此正则表达式不适用于子块中的嵌套块,并且不适用于除块之外的父块内的任何其他内容。但是你没有提到这些。
这里是online version.
$str = 'Block1 {
block1child1 {
}
block1child2 {
}
block1child3 {
}
}
Block2 {
block2child1 {
}
block2child2 {
}
}';
$str = preg_replace('([\w\d]+)', '"[=10=]"', $str);
$str = str_replace(' {', ': {', $str);
$str = str_replace('}', '},', $str);
$str = preg_replace('/\}\,[.\n]*?}/', '}}', $str);
$str = json_decode('{' . substr($str, 0, strlen($str) - 1) . '}', true);
var_export($str);
array (
'Block1' =>
array (
'block1child1' =>
array (
),
'block1child2' =>
array (
),
'block1child3' =>
array (
),
),
'Block2' =>
array (
'block2child1' =>
array (
),
'block2child2' =>
array (
),
),
)
- 将字符串转换为 JSON
- 将JSON转换为数组
您需要使用递归模式:
$pattern = '~(\w+)\s*{([^{}]*(?:{(?2)}[^{}]*)*)}~';
详情:
~ # delimiter
(\w+) # capture group 1: block name
\s* # eventual whitespaces
{
( # capture group 2
[^{}]* # all that isn't a curly bracket
(?:
{ (?2) } # reference to the capture group 2 subpattern
[^{}]*
)*
)
}
~
请注意,对捕获组 2 的引用在捕获组 2 本身内部,这就是该模式递归的原因。
你好,我有 2 个父(或更多...)块和其中的许多子块。
Block1 {
blockchild1 {
}
blockchild2 {
}
, ...
}
Block2 {
blockchild1 {
}
blockchild2 {
}
, ...
}
我想使用 php 正则表达式并首先获取
中的所有父块([a-z-0-9]*)\s*[{](.*?)[}]
但是这个正则表达式在到达第一个子块关闭时停止 }
意味着第一个数据接收是
Block1 {
blockchild1 {
}
但我想得到这样的东西
array 1 = Block1
array 2 = blockchild1 {
}
blockchild2 {
}
, ...
我希望正则表达式传递子块 [}]
并获取父块内的所有内容。我的正则表达式是 PCRE (PHP)
试试这个:
$str = 'Block1 {
block1child1 {
}
block1child2 {
}
block1child3 {
}
}
Block2 {
block2child1 {
}
block2child2 {
}
}';
$sub = '(\s*[a-z-0-9]*\s*{.*?}\s*)*';
preg_match_all("/([a-z-0-9]*)\s*{($sub)}/sim", $str, $matches, PREG_SET_ORDER);
var_dump($matches);
我使用变量 $sub
来阐明方法。它returns:
$matches[0][1] = 'Block1';
$matches[0][2] = '
block1child1 {
}
block1child2 {
}
block1child3 {
}
';
它包含 Block2 的正确输出($matches
的索引 1
)。
此正则表达式不适用于子块中的嵌套块,并且不适用于除块之外的父块内的任何其他内容。但是你没有提到这些。
这里是online version.
$str = 'Block1 {
block1child1 {
}
block1child2 {
}
block1child3 {
}
}
Block2 {
block2child1 {
}
block2child2 {
}
}';
$str = preg_replace('([\w\d]+)', '"[=10=]"', $str);
$str = str_replace(' {', ': {', $str);
$str = str_replace('}', '},', $str);
$str = preg_replace('/\}\,[.\n]*?}/', '}}', $str);
$str = json_decode('{' . substr($str, 0, strlen($str) - 1) . '}', true);
var_export($str);
array (
'Block1' =>
array (
'block1child1' =>
array (
),
'block1child2' =>
array (
),
'block1child3' =>
array (
),
),
'Block2' =>
array (
'block2child1' =>
array (
),
'block2child2' =>
array (
),
),
)
- 将字符串转换为 JSON
- 将JSON转换为数组
您需要使用递归模式:
$pattern = '~(\w+)\s*{([^{}]*(?:{(?2)}[^{}]*)*)}~';
详情:
~ # delimiter
(\w+) # capture group 1: block name
\s* # eventual whitespaces
{
( # capture group 2
[^{}]* # all that isn't a curly bracket
(?:
{ (?2) } # reference to the capture group 2 subpattern
[^{}]*
)*
)
}
~
请注意,对捕获组 2 的引用在捕获组 2 本身内部,这就是该模式递归的原因。