我试图制定一个用于文本的正则表达式。使用内存中的变量并没有给出相同的结果。
以下正则表达式提供了返回我期望的$1
和$2
。 rw
结果各不相同。这些位置可能会有所不同:我希望提取数据而不管字符串中的位置。
\/vol\/(\w+)\?(\w+|\s+).*rw=(.*\w+)
我的数据:
_DATA_
/vol/vol1 -sec=sys,rw=h1:h2,anon=0
/vol/vol1/q1 -sec=sys,rw=h3:h4,anon=0,ro=h1:h2
/vol/vol2/q1 -sec=sys,root=host5,ro=h3:h5,rw=h1:h2,anon=0
我试图捕获第二组和第三组(如果它是一个空格,它应该返回一个空格),以及rw
,ro
和{{1}中的条目列表}}
答案 0 :(得分:1)
表达式(.*\w+)
将匹配行中的最后一个单词字符。你正在寻找的是([0-9a-z:]+)
答案 1 :(得分:1)
根据你对ikegami回复的评论猜测,也许以下内容会给你想要的结果。
#!/usr/bin/perl
use strict;
use warnings;
my @keys = qw/ rw ro root /;
my $wanted = join "|", @keys;
my %data;
while (<DATA>) {
my ($path, $param) = split;
my ($vol, $q) = (split '/', $path)[2,3];
my %tmp = map {split /=/} grep /^(?:$wanted)/, split /,/, $param;
$data{$vol}{$q // ' '} = \%tmp;
}
use Data::Dumper; print Dumper \%data;
__DATA__
/vol/vol1 -sec=sys,rw=h1:h2,anon=0
/vol/vol1/q1 -sec=sys,rw=h3:h4,anon=0,ro=h1:h2
/vol/vol2/q1 -sec=sys,root=host5,ro=h3:h5,rw=h1:h2,anon=0
Data :: Dumper的输出是:
$VAR1 = {
'vol2' => {
'q1' => {
'ro' => 'h3:h5',
'root' => 'host5',
'rw' => 'h1:h2'
}
},
'vol1' => {
' ' => {
'rw' => 'h1:h2'
},
'q1' => {
'ro' => 'h1:h2',
'rw' => 'h3:h4'
}
}
};
更新: 你能告诉我grep中的(?:)含义是什么吗?
(?: . . .)
是一个非捕获组。在这种情况下使用它是因为正则表达式的开头有^
。如果没有分组,正则表达式会尝试匹配位于字符串开头的ro
或rw
或root
字符串中的任何位置(而不仅仅是开头)。
/^ro|rw|root/
而不是/^(?:ro|rw|root)/
第二个表达式有助于搜索,因为它知道只在字符串的开头为所有3个模式尝试匹配,而不是尝试匹配字符串中的任何位置(虽然在你的情况下只有3次交替匹配尝试 - 所以,这里不会产生巨大的差异)。但是,仍然是一个很好的做法。
(//&#39;&#39;)代表什么?
那是定义的或运算符。表达式$q // ' '
表示如果将空格定义为或,则使用$q
作为哈希中的键。
你在原来的帖子中说过我试图捕获第二组和第三组(如果它是一个空格,它应该返回一个空格)。
当分割时,{p>$q
可能未定义,my ($vol, $q) = (split '/', $path)[2,3];
只有vol
而不是q
,例如此数据行(/vol/vol1 -sec=sys,rw=h1:h2,anon=0
)。
答案 2 :(得分:0)
不知道你想要什么,但正则表达式不会在这里成为一个好的解析器。
while (<DATA>) {
my ($path, $opts) = split;
my %opts =
map { my ($k,$v) = split(/=/, $_, 2); $k=>$v }
split(/,/, $opts);
...
}
(my %opts = split(/[,=]/, $opts);
可能就足够了。)