字符串上的正则表达式

时间:2016-02-04 00:11:11

标签: regex perl

我试图制定一个用于文本的正则表达式。使用内存中的变量并没有给出相同的结果。

以下正则表达式提供了返回我期望的$1$2rw结果各不相同。这些位置可能会有所不同:我希望提取数据而不管字符串中的位置。

\/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

我试图捕获第二组和第三组(如果它是一个空格,它应该返回一个空格),以及rwro和{{1}中的条目列表}}

3 个答案:

答案 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中的(?:)含义是什么吗?

(?: . . .)是一个非捕获组。在这种情况下使用它是因为正则表达式的开头有^。如果没有分组,正则表达式会尝试匹配位于字符串开头的rorwroot字符串中的任何位置(而不仅仅是开头)。

/^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);可能就足够了。)