我有一个大型多维结构的文件,类似于json,但不足以让我使用json库。
数据看起来像这样:
alpha {
beta {
charlie;
}
delta;
}
echo;
foxtrot {
golf;
hotel;
}
我正在尝试构建的正则表达式(对于preg_match_all)应匹配每个顶级父级(由{}大括号分隔),以便我可以通过匹配来递归,构建一个代表数据的多维php数组。
我尝试的第一个正则表达式是/(?<=\{).*(?=\})/s
,它贪婪地匹配大括号内的内容,但是这不太正确,因为当顶级中有多个兄弟时,匹配太贪婪了。示例如下:
使用正则表达式/(?<=\{).*(?=\})/s
匹配为:
匹配1:
beta {
charlie;
}
delta;
}
echo;
foxtrot {
golf;
hotel;
相反,结果应该是: 比赛1:
beta {
charlie;
}
delta;
比赛2:
golf;
hotel;
所以正则表达式向导,我在这里缺少什么功能或者我需要以某种方式解决这个问题吗?任何提示非常欢迎:))
答案 0 :(得分:2)
您不能 1 使用正则表达式执行此操作。
或者,如果要匹配深度到浅的块,可以使用\{[^\{\}]*?\}
和preg_replace_callback()
来存储值,然后返回null
以从字符串中删除它。回调将需要相应地嵌套值。
$heirarchalStorage = ...;
do {
$string = \preg_replace_callback('#\{[^\{\}]*?\}#', function($block)
use(&$heirarchalStorage) {
// do your magic with $heirarchalStorage
// in here
return null;
}, $string);
} while (!empty($string));
不完整,未经测试且无保修。
这种方法要求字符串也包含在{}
中,否则最后的匹配不会发生,你将永远循环。
这是一个糟糕的很多(效率低下的)工作,可以通过众所周知的交换/存储格式(如JSON)轻松解决。
1 我打算“你可以,但...... ”,但我只想再说一次,“ 你不能 “ 2
2 不要
答案 1 :(得分:2)
当然,您可以使用正则表达式执行此操作。
preg_match_all(
'/([^\s]+)\s*{((?:[^{}]*|(?R))*)}/',
$yourStuff,
$matches,
PREG_SET_ORDER
);
这给我以下匹配:
[1]=>
string(5) "alpha"
[2]=>
string(46) "
beta {
charlie;
}
delta;
"
和
[1]=>
string(7) "foxtrot"
[2]=>
string(22) "
golf;
hotel;
"
稍微分解一下。
([^\s]+) # non-whitespace (block name)
\s* # whitespace (between name and block)
{ # literal brace
( # begin capture
(?: # don't create another capture set
[^{}]* # everything not a brace
|(?R) # OR recurse
)* # none or more times
) # end capture
} # literal brace
仅为了您的信息,这适用于n级深层次的支撑。
答案 2 :(得分:0)
我认为您可以通过匹配[a-zA-Z0-9][:blank]+{
和}
来使用preg_split
获得一些内容。您将能够通过查看结果来构建数组。使用递归函数,当匹配开始标记时,该函数会更深,而在结束标记上则更高。
否则,最干净的解决方案是实现ANTLR语法!