我正在尝试解析具有此模式的字符串
src [interface_name:source_address[/source_port]]
括号中的部分是可选的。所以有3种可能的变种
src
src LAN:10.115.1.204
src LAN:10.115.1.204/8080
我想从此字符串中捕获界面,源IP 和源端口。
我的第三个变体的正则表达式是
($srcinterface,$srcip,$src_port) = m/^src (.*?):(.*?)\/(.*?)/;
但我不知道如何制作适用于所有3种变体的正则表达式。
修改 问题的大部分是像src dst信息也从系统接收,我需要重复正则表达式。见下面的字符串: -
src dst outside:125.22.32.192
src outside:182.201.183.178 dst outside:125.22.32.192
src outside:182.201.183.178/5525 dst outside:125.22.32.192/8595
答案 0 :(得分:1)
改为使用:
/^src(?> (\w++):((?>[0-9]{1,3}\.){3}[0-9]{1,3})(?>\/([0-9]++))?)?/
示例脚本:
#!/usr/bin/perl
use strict;
my $str = "src
src LAN:10.115.1.204
src LAN:10.115.1.204/8080";
my $i = 0;
while($str =~ /^src(?> (\w++):((?>[0-9]{1,3}\.){3}[0-9]{1,3})(?>\/([0-9]++))?)?/gm) {
print "\n[match " . ++$i . "]"
. "\nWhole match : $&"
. "\nCapture group 1: $1"
. "\nCapture group 2: $2"
. "\nCapture group 3: $3\n";
}
对于更宽松的模式,您可以使用:
/^src(?> (\w++):([^\/\n]++)(?>\/([^\n]++))?)?/gm
或者这个:
/^src(?> (\w++):([^\/\n]++)(?>\/(\S++))?)?/gm
这些模式的想法是使用否定的字符类,例如[^\/\n]
表示所有不是斜杠或换行符的字符。您可以轻松地根据需要添加或删除字符来调整这些类。
答案 1 :(得分:1)
我不是Perl大师,但也许这有效:
($srcinterface,$srcip,$src_port) = m/^src\s*(?:(.*?):(.*?)(?:\/(.*?))?)?/;
?:
应该将其设为隐藏组,组末尾的?
使其成为可选组。
嗯,可读性变得混乱......
答案 2 :(得分:1)
目前尚不清楚哪些字段是可选字段,但您可以简单地拆分正则表达式来分隔那些字段。
在此程序中,@fields
数组将包含指定的字段数。假设可选字段从右侧消失(即,没有源地址没有接口名称,没有源端口,没有名称和地址),您可以简单地计算@fields
中的字段以查看提供的字段。
use strict;
use warnings;
use Data::Dump;
for (
'src',
'src LAN:10.115.1.204',
'src LAN:10.115.1.204/8080') {
my @fields = split /[\/\s]+/;
dd \@fields;
}
<强>输出强>
["src"]
["src", "LAN:10.115.1.204"]
["src", "LAN:10.115.1.204", 8080]
答案 3 :(得分:1)
这个正则表达式对我有用
($srcinterface, $srcip, $src_port) = m@^src (?:([^:]+):([^/]+))?(?(1)(?:/(.+))?)@;
注意:
我正在使用否定的字符类(例如[^:]
)和+
因为.*?
会导致变体2和3出现问题,因为正则表达式遵循以下.*?
定义不明确(简单地说,.*?
将与零长度字符串匹配)。
我将 interface_name:source_address 部分设为可选,并附上(?:...)?
然后我使用了条件正则表达式(?(1)pattern)
,这意味着“如果捕获组1成功匹配则匹配pattern
”
实际上,如果匹配 interface_name:source_address ,请查找 / port
由于 / port 是可选的,我将该部分包装在条件正则表达式中的另一个(?:...)?
里面。
对于它的价值,我认为Borodin's split-based answer 方式更简单,Casimir et Hippolyte's regex-based answer在稳健性方面更好,因为它实际上验证了每个组件。我只是为了完成而发布这个。