我希望能够将/ proc / drbd的内容解析成数组以便使用数据。我确信有一些捷径或技巧可以做到这一点,但对于我的生活,它是我的目标!
我认为这是一些复杂的正则表达式的工作?
要解析的文本是:
version: 8.4.3 (api:1/proto:86-101)
srcversion: 6551AD2C98F533733BE558C
1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:1055689 nr:0 dw:7181 dr:1050351 al:6 bm:64 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
2: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
ns:0 nr:1048508 dw:1048508 dr:0 al:0 bm:64 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
数组可能如下所示:
{
'version' -> '8.4.3',
'api' -> '1',
'proto' -> '86-101',
'srcversion' -> '6551AD2C98F533733BE558C',
'devices' -> array { '1' -> array { 'cs' -> 'Connected', 'ro' -> 'Primary/Secondary', ... , 'oos' -> 0 },
'2' -> array { 'cs' -> 'Connected', 'ro' -> 'Secondary/Primary', ... , 'oos' -> 0 } }
}
我没有任何我为此尝试的东西的例子,因为我甚至不确定从哪里开始。通常我会用一堆爆炸或preg_match来做这件事,但我很确定这不是正确的解决方案,而且我不确定如何处理分布在两条线上的一个实体的数据!
编辑:
设备重建期间设备数据格式还有另一种变体:
3: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r----
ns:0 nr:284320 dw:284320 dr:0 al:0 bm:17 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:764188
[====>...............] sync'ed: 27.4% (764188/1048508)K
finish: 0:15:55 speed: 416 (320) K/sec
我无法弄清楚如何忽略这些可选的第二行。
((\.+)\R)?
((\.+)\R)?
内部正则表达式的结尾显然不起作用:(
提前致谢!
答案 0 :(得分:1)
您可以使用正则表达式和编程逻辑的组合,请参阅a demo on ideone.com
该方法对version
,api
,proto
和srcversion
使用外部正则表达式,并为devices
使用内部正则表达式。除了实际的正则表达式(在多行和详细模式下),线索是使用PREG_SET_ORDER
和命名的捕获组,因此可以在之后循环匹配。内部部分包括分割线和匹配的键/值对:
<?php
$string = <<<EOS
version: 8.4.3 (api:1/proto:86-101)
srcversion: 6551AD2C98F533733BE558C
1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:1055689 nr:0 dw:7181 dr:1050351 al:6 bm:64 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
2: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
ns:0 nr:1048508 dw:1048508 dr:0 al:0 bm:64 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
3: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r----
ns:0 nr:284320 dw:284320 dr:0 al:0 bm:17 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:764188
[====>...............] sync\'ed: 27.4% (764188/1048508)K
finish: 0:15:55 speed: 416 (320) K/sec
EOS;
$outerregex = '~
^version:\s
(?P<version>[\d.]+)\s
\(
api:(?P<api>\d+).+?
proto:(?P<proto>[-\d]+)
\)\R
srcversion:\s(?P<srcversion>.+)\R{2}
(?P<devices>(?:\s\d(?:.+\R){2})+)
~xm';
$outerkeys = array("version", "api", "proto", "srcversion");
$output = array();
preg_match_all($outerregex, $string, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$arr = array();
// save the outer key/value pairs
foreach ($outerkeys as $key) $arr[$key] = $match[$key];
$arr["devices"] = array();
// split the device to have separate lines
$lines = preg_split('~\R\s+\d:~', $match["devices"]);
// loop over these lines
foreach ($lines as $line) {
$tmp = array();
preg_match_all('~(?P<key>\w+):(?P<value>\S+)~', $line, $linematches, PREG_SET_ORDER);
foreach ($linematches as $linematch)
$tmp[$linematch["key"]] = $linematch["value"];
$arr["devices"][] = $tmp;
}
$output[] = $arr;
}
print_r($output);
?>