我们有一个防火墙,我们在其中使用PHP脚本处理配置,然后使其可在网站上查看。
今天发生了一个问题。问题在于评论字段。那里应该没有换行符。因此,我希望PHP在注释字段中删除换行符(用空格替换)。
我对正则表达式的经验有限,但是我已经使用regex101.com和stackoverflow帖子的帮助建立了很多东西。由于某种原因,我似乎无法解决这个问题。
配置存储在一个文本文件中,如下所示:
config firewall policy
edit 2
set uuid 79123-123-51e6-bb5f-123f123df
set srcintf "any"
set dstintf "any"
set srcaddr "h-host1" "h-host2" "h-host3"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set utm-status enable
set logtraffic disable
set comments "This is a comment for this rule
This is an additional comment for that rule"
set ips-sensor "Sensor1"
next
edit 1
set uuid f123-34ab-1dcf-a123dc123
set srcintf "any"
set dstintf "any"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set utm-status enable
set logtraffic all
set comments "This is a one line comment for a rule"
set ips-sensor "Sensor1"
next
end
在此示例中,有1条注释带有换行符。 我尝试过的正则表达式存储在这里:https://regex101.com/r/0jaDjL/1/
它应该做的是先查找“设置注释” ,然后查找下一个引号” ,这样中间的换行符可以替换为一个空间。
所以这里:
set comments "This is a comment for this rule
This is an additional comment for that rule"
在这里成为这个:
set comments "This is a comment for this rule This is an additional comment for that rule"
regex似乎可以在线上正确地抓取:https://regex101.com/r/0jaDjL/1/
但是不在我的环境中。例如,PHP不知道'g'参数。而且似乎找到了最后一个报价,而不是第一个下一个报价。
为了更好地了解会发生什么,我的编码现在看起来像这样:
<?php
function blaat($matches){
echo '<pre>';
echo PHP_EOL .'AAAAAAAAAAAAAAAAAAAA#'.$matches[0].'#AAAAAAAAAAAAAAAAAAAA';
echo PHP_EOL .'BBBBBBBBBBBBBBBBBBBB#'.$matches[1].'#BBBBBBBBBBBBBBBBBBBB';
echo PHP_EOL .'CCCCCCCCCCCCCCCCCCCC#'.$matches[2].'#CCCCCCCCCCCCCCCCCCCC';
echo PHP_EOL .'DDDDDDDDDDDDDDDDDDDD#'.$matches[3].'#DDDDDDDDDDDDDDDDDDDD';
echo PHP_EOL .'EEEEEEEEEEEEEEEEEEEE#'.$matches[4].'#EEEEEEEEEEEEEEEEEEEE';
//echo PHP_EOL .'FFFFFFFFFFFFFFFFFFFF#'.$matches[5].'#FFFFFFFFFFFFFFFFFFFF';
}
$PathAndFile='C:\Temp\sys_config.txt';
preg_replace_callback(
'/^(\s*?)(set comments ")(\X+)("$)/Um',
'blaat',
trim(file_get_contents($PathAndFile))
);
但是输出不是我想要的。
AAAAAAAAAAAAAAAAAAAA#
set comments "This is a comment for this rule
This is an additional comment for that rule"
set ips-sensor "Sensor1"
next
edit 1
set uuid f123-34ab-1dcf-a123dc123
set srcintf "any"
set dstintf "any"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set utm-status enable
set logtraffic all
set comments "This is a one line comment for a rule"#AAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBB#
#BBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCC#set comments "#CCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDD#This is a comment for this rule
This is an additional comment for that rule"
set ips-sensor "Sensor1"
next
edit 1
set uuid f123-34ab-1dcf-a123dc123
set srcintf "any"
set dstintf "any"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set utm-status enable
set logtraffic all
set comments "This is a one line comment for a rule#DDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEE#"#EEEEEEEEEEEEEEEEEEEE
在注释字段中有关替换换行符的任何提示吗?
答案 0 :(得分:1)
您需要在此处preg_replace_callback()
的(嵌套)呼叫:
<?php
$regex = '~^\s*set comments\s\K"[^"]*"~m';
$data = preg_replace_callback($regex, function($match) {
return preg_replace("~\R\s*~", " ", $match[0]);
},
$data);
echo $data;
?>
有关表达式,请参见a demo on ideone.com和a demo on regex101.com。
^ # match start of the line in multiline mode
\s* # zero or more whitespaces
set comments # set comments literally
\s # whitespace
\K # "forget" what's been matched thus far
"[^"]*" # anything between double quotes ("...")
return preg_replace("~\s+~", " ", $match[0]);
答案 1 :(得分:1)
您可以为此创建一个更简单的正则表达式,只需选择set comment "
之后引号之间的所有文本,然后将所有新行替换为匹配项中的空格。
正则表达式的工作方式如下:https://regex101.com/r/AU2VJJ/1
这是您可以使用的php演示:
<?php
$text = <<<EOT
config firewall policy
edit 2
set srcintf "any"
set comments "This is a comment for this rule
This is an additional comment for that rule"
set ips-sensor "Sensor1"
next
edit 1
set srcintf "any"
set comments "This is a one l
ine comment for a rule"
set ips-sensor "Sensor1"
set comments "This is a comment for this rule
This is an additional comment for that rule
And one more."
next
edit 3
set srcintf "any"
set comments "This is a one l
ine comment for a rule"
set ips-sensor "Sensor1"
set comments "This is a comment for this rule
Another comment
More comments
And more
And more
And one more."
next
end
EOT;
$text = preg_replace_callback('/(set comments ")([^"]+)(")/', function($matches) {
// $matches[1] is `set comments"` text
// $matches[2] is everything between `set comments"` and closing `"`
// $matches[3] is closing `"`
return $matches[1] . str_replace("\n", " ", $matches[2]) . $matches[3];
}, $text);
echo $text;