我该如何使用Perl提取字符串中等号后面的值?

3
我有一个字符串,如下所示。
field1=1 field2=2 field3=abc

我希望将此输出为:
2,1,abc

有什么想法可以帮我完成这个任务吗?我可以编写一个小的C或Java程序来实现,但我正在尝试寻找一种在Perl中简单实现它的方法。


你是不是真的想交换上面的 1 和 **2**? - Sinan Ünür
1
这与HTTP查询字符串有关吗?如果这是一个迂回的问题,或者你可以处理&或分号分隔字段,那么你可以使用CPAN上的众多CGI模块中的任何一个。 - jsoverson
11个回答

6
use strict;
use warnings;

my $string = 'field1=1 field2=2 field3=abc';
my @values = ($string =~ m/=(\S+)/g);
print join(',', @values), "\n";

这会以错误的顺序输出字段。 小问题:如果任何值包含等号,它也无法正常工作。 - Lars Haugseth

5
#!/usr/bin/perl

use strict;
use warnings;

# Input string
my $string = "field1=1 field2=2 field3=abc";
# Split string into a list of "key=value" strings
my @pairs = split(/\s+/,$string);
# Convert pair strings into hash
my %hash = map { split(/=/, $_, 2) } @pairs;
# Output hash
printf "%s,%s,%s\n", $hash{field2}, $hash{field1}, $hash{field3};   # => 2,1,abc
# Output hash, alternate method
print join(",", @hash{qw(field2 field1 field3)}), "\n";

加1分,因为没有使用正则表达式。但是,split(/\s+/,$string)也可以更简单地表示为split(' ',$string)。 - glenn jackman
只要有单个空格,就返回True。 - Lars Haugseth

2

在列表上下文中使用m//g

#!/usr/bin/perl

use strict;
use warnings;

my $x = "field1=1 field2=2 field3=abc";

if ( my @matches = $x =~ /(?:field[1-3]=(\S+))/g ) {
    print join(',', @matches), "\n";
}

__END__

输出:

C:\Temp> klm
1,2,abc

2
 $_='field1=1 field2=2 field3=abc';
 $,=',';
 say /=(\S+)/g

让我们来玩 Perl 高尔夫球:D

2
如果我们正在打高尔夫球... perl -E "$_='field1=1 field2=2 field3=abc';$,=',';say /=(\S+)/g" - Michael Carman

1

有几种方法可以做到这一点:

  • 正则表达式匹配
my $s = "field1=1 field2=2 field3=abc";
$s =~ /field1=(\w*) field2=(\w*) field3=(\w*)$/; //pick out each field
print $1,$2,$3;'
12abc

分割匹配的字符串
my $s = "field1=1 field2=2 field3=abc"; 
my @arr = split / /, $s; print @arr,"\n"; //make an array of name=value pairs
my @vals = map { @pairs = split /=/, $_; $pairs[1] } @arr;  //get the values only from each pair
print @vals'
field1=1field2=2field3=abc
12abc
  • 将其分割并放入哈希表中(我认为这是最有用的方法)
my $s = "field1=1 field2=2 field3=abc"; 
my @arr = split / /, $s;  
my %pairs = map { split=/, $_; } @arr; 
print $pairs{field1}, $pairs{field2}, $pairs{field3}
12abc

1
my $str = 'field1=1 field2=2 field3=abc';
print(join(',', map { (split('=', $_))[1] } split(' ', $str)));

0

假设您的排序是一个打字错误:


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

my $str='a=1 b=2 c=abc';
my @v;
while ($str =~ /=(\S+)/g) {
    push @v, $1;
}
print join (',', @v);

1
不需要循环。您可以在列表上下文中使用m//g一次捕获所有匹配项。 - Michael Carman

0
my $a = "field1=1 field2=2 field3=abc";
my @f = split /\s*\w+=/, $a;
shift(@f);
print join(",", @f), "\n";

0
$string="field1=1 field2=2 field3=abc";
@s=split /\s+/,$string;
$temp=$s[1];$s[1]=$s[0];$s[0]=$temp;
foreach (@s){s/.*=//; push(@a,$_ );}
print join(",",@a);

0
如果你需要键和值,我建议将它们放入哈希表中。你可以直接捕获"="两边的内容,并将其放入哈希表中。
use strict;
use warnings;

my $str = 'field1=1 field2=2 field3=abc';

my %fields = $str =~ / (\S+) \s* = \s* (\S+) /xg;

use YAML;
print Dump \%fields
---
field1: 1
field2: 2
field3: abc

如需更多信息,请阅读{{link1:perldoc perlre}}。

如果您是初学者,您可能想阅读{{link2:perldoc perlretut}}。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接