需要regexp来帮助我从双引号中提取数据

时间:2013-12-21 20:53:37

标签: regex perl

我已经在stackoverflow中找到了这个问题的答案但是无法获得可接受的结果。抱歉!

我有一个如下所示的数据文件:

share "SHARE1" "/path/to/some/share" umask=022 maxusr=4294967295 netbios=SOMECIFSHOST
share "SHARE2" "/path/to/a/different/share with spaces in the dir name" umask=022 maxusr=4294967295 netbios=ANOTHERCIFSHOST

...我需要从中提取双引号内的值。换句话说,我想得到这样的东西:

share,SHARE1,/path/to/some/share/,umask=022,maxusr=4294967295,netbios=SOMECIFSHOST
share,SHARE2,/path/to/a/different/share with spaces in the dir name,umask=022,maxusr=4294967295,netbios=ANOTHERCIFSHOST

我发现的棘手部分是尝试提取引号内的数据。这里提出的建议对我没用,所以我猜我做错了。我还需要从每一行的双引号字符串中提取BOTH值,而不仅仅是第一个;我想通过拆分空格可以很容易地解析剩余的东西。

如果它是相关的,我在RHEL盒子上运行它,我需要使用Perl使用regexp将其拉出来。

THX!

6 个答案:

答案 0 :(得分:2)

一种选择是将您的数据视为CSV文件,并使用Text::CSV_XS对其进行解析,将分隔符设置为空格:

use strict;
use warnings;
use Text::CSV_XS;

my $csv = Text::CSV_XS->new( { binary => 1, sep_char => ' ' } )
  or die "Cannot use CSV: " . Text::CSV->error_diag();

open my $fh, "<:encoding(utf8)", "data.txt" or die "data.txt: $!";
while ( my $row = $csv->getline($fh) ) {
    print join ',', @$row;
    print "\n";
}
$csv->eof or $csv->error_diag();
close $fh;

数据集输出:

share,SHARE1,/path/to/some/share,umask=022,maxusr=4294967295,netbios=SOMECIFSHOST
share,SHARE2,/path/to/a/different/share with spaces in the dir name,umask=022,maxusr=4294967295,netbios=ANOTHERCIFSHOST

希望这有帮助!

答案 1 :(得分:1)

你可以这样做:

如果引号内的字面引号使用反斜杠进行转义:share "SHA \" RE1" ...

$str =~ s/(?|"((?>[^"\\]++|\\{2}|\\.)*)"|()) /$1,/gs;

如果使用其他引号转义字面引号:share "SHA "" RE1" ...

$str =~ s/(?|"((?>[^"]++|"")*)"|()) /$1,/g;

如果您绝对确定所有数据中的引号之间没有转义引号:

$str =~ s/(?|"([^"]*)"|()) /$1,/g;

答案 2 :(得分:0)

试试这个。

[^\" ]*

它选择除了引号和空格之外的每个字符。

答案 3 :(得分:0)

我不确定我是否理解了这个问题,你在文中说了一件事但是这个例子说了一些不同的东西,不管怎样,试试这个:

#!/usr/bin/env perl
use strict;
use warnings;

while (<DATA>) {
  chomp;
  my @matches = $_ =~ /"(.*?)"/g;
  print "@matches\n";
}

__DATA__
share "SHARE1" "/path/to/some/share" umask=022 maxusr=4294967295 netbios=SOMECIFSHOST
share "SHARE2" "/path/to/a/different/share with spaces in the dir name" umask=022 maxusr=4294967295 netbios=ANOTHERCIFSHOST

输出:

$ ./p.pl 
SHARE1 /path/to/some/share
SHARE2 /path/to/a/different/share with spaces in the dir name

答案 4 :(得分:0)

my $str = 'share "SHARE1" "/path/to/some/share" umask=022 maxusr=4294967295 netbios=SOMECIFSHOST';
$str =~ s/"?\s*"\s*/,/g;
print $str;

这个正则表达式替换如下:
“空间”=,
“space =,
空间“=,
“”=,

答案 5 :(得分:0)

#!/usr/bin/env perl
while(<>){  
    my @a = split /\s+\"|\"\s+/ , $_;      # split on any spaces + ", or any " + spaces
    for my $item ( @a ) {   
        if ( $item =~ /\"/ ) {          # if there's a quote, remove
            $item =~ s/\"//g;               
        } elsif ( $item !~ /\"/ ){      # else just replace spaces with comma
            $item =~ s/\s+/,/g; 
        }               
    }
    print join(",", @a);
    print "\n"; 
}

输出:

share,SHARE1,/path/to/some/share,umask=022,maxusr=4294967295,netbios=SOMECIFSHOST,
share,SHARE2,/path/to/a/different/share with spaces in the dir name,umask=022,maxusr=4294967295,netbios=ANOTHERCIFSHOST,

留下你删除最后一个逗号:)