我有这样的配置文件:
#DHCP Server Configuration file.
deny unknown-clients;
subnet 10.8.140.2 netmask 255.255.255.255 {
host example{
optian:param;
}
host example2{
option2:param2;
}
}
subnet 20.8.110.1 netmask 255.255.255.255 {
}
我需要找到所有子网块。 问题是子网块可以包含主机块(带有花括号)。我不能构建正则表达式以匹配那些。
所以结果应该是:
1.子网10.8.140.2网络掩码255.255.255.255 {... host {...} host {...}}
2.子网20.8.110.1网络掩码255.255.255.255 {...}
答案 0 :(得分:3)
你没有命名你的编程语言。下面是一个在PHP(PCRE)中使用recursive pattern的示例:
<?php
$conf = file_get_contents('/path/to/dhcp.conf');
# We use a recursive pattern, check the link I posted above
$pattern = '/(subnet.*?)?\{((?>[^{}]+)|(?R))*\}/';
preg_match_all($pattern, $conf, $matches);
foreach($matches[0] as $match) {
echo $match . PHP_EOL . PHP_EOL;
}
PHP使用 Perl兼容的正则表达式,您可以在Perl或使用相同引擎并支持递归的其他语言中使用相同的模式。
顺便说一下,语法高亮似乎对模式很有趣,但是不语法错误。
答案 1 :(得分:1)
Regex can't be used to match nested pattern of arbitrarily deep nesting.
但在你的情况下,如果子网块遵循骨架 子网|主机|选项,则深度是有限的。
在这里蛮力我得到了:
((|\s|\n)*subnet(|\s|\n)*((\d{1,3}.){3}(\d{1,3}))(|\s|\n)*netmask(|\s|\n)*((\d{1,3}.){3}(\d{1,3}))(|\s|\n)*\{(|\s|\n)+((|\s|\n)+host(|\s|\n)*(\w+)(|\s|\n)*\{(|\s|\n)*(\w*)\:(\w*)\;(|\s|\n)*\}(|\s|\n)*)*\})
丑陋的AF。您可以对其进行测试here。
我经常使用(|\s|\n)*
,实际上我在子网和第一个ip:subnet10.4.4.2
之间没有空格,这是不好的。
但您可能在主机名和左括号之间不允许使用空格,例如代码:host example{
。