Regex 用perl从字符串中提取数据

Regex 用perl从字符串中提取数据,regex,perl,Regex,Perl,有字符串“-test aaaa-machine bbb-from ccc” 如何使用常规方法提取“aaaa”、“bbb”、“ccc”? 偶数字符串为“-fromcc testaaa machine bbb” (不同的顺序,几个空格…) 我尝试了一些代码,但总是得到无效数据。 $str = "-test aaaa -machine bbb -from ccc"; $str =~ /-test\s*(.*)\s*/; 印刷品 我还想处理以下情况 -test aa_aa -machine

有字符串“-test aaaa-machine bbb-from ccc”

如何使用常规方法提取“aaaa”、“bbb”、“ccc”?

偶数字符串为“-fromcc testaaa machine bbb”
(不同的顺序,几个空格…)

我尝试了一些代码,但总是得到无效数据。

$str = "-test aaaa     -machine  bbb  -from ccc";
$str =~ /-test\s*(.*)\s*/;
印刷品

我还想处理以下情况

-test aa_aa -machine aab-baa-aba -from ccc

你不必使用正则表达式,你可以使用散列

use strict;
use warnings;
use Data::Dumper;

my $str = '-test aaaa   -machine  bbb  -from ccc';
my %field = split ' ', $str;
print Dumper(\%field);
输出:

$VAR1 = {
          '-from' => 'ccc',
          '-machine' => 'bbb',
          '-test' => 'aaaa'
        };
无论顺序是什么,
拆分
返回一个成对数组(形状为
[word1,word2,word3,word4,word5,word6]
word1
word3
word5
将是
-field\u name
),当分配给散列时,将以现在的方式创建它,例如,如果要在
-test
之后获取字符串,只需通过键入
$field{“-test”}
来访问它,并对其执行任何操作


编辑:单词之间有多少空格或单词中有什么字符都无关紧要。它对所有情况都是一样的,只要你把它的格式保持在
-某个字段某物-另一个字段另一个字段某物…

我将回答(我认为)你的问题背后的问题-而不是你问的问题

在我看来,您正在解析命令行选项。因此,请使用命令行选项解析器,而不是自己重新设计。是标准Perl发行版的一部分

#!/usr/bin/perl

use strict;
use warnings;
# We use modern Perl (here, specifically, say())
use 5.010;

use Getopt::Long 'GetOptionsFromString';
use Data::Dumper;

my %options;

my $str = '-test aa_aa -machine aab-baa-aba -from ccc';
GetOptionsFromString($str, \%options, 'test=s', 'machine=s', 'from=s');

say Dumper \%options;
通常,在解析
@ARGV
中可用的命令行选项时,您会使用函数
GetOptions()
。我不确定这些选项是如何在字符串中结束的,但是对于这种情况,有一个有用的
GetOptionsFromString()
函数

更新:以解释代码不起作用的原因

$str = "-test aa_aa     -machine  aab-baa-aba  -from ccc";
$str =~ /-test\s*(.*)\s*/;
您正在捕获与
(.*)
匹配的内容。但是
*
是贪婪的。也就是说,它尽可能多地匹配数据。在本例中,这意味着它匹配到行尾。有(至少!)几种方法可以解决这个问题

1/通过添加
使匹配不贪婪

$str =~ /-test\s*(.*?)\s*/;
2/更明确地说明您要查找的内容-在本例中为非空白字符

$str =~ /-test\s*(\S*)\s*/;

这应该能奏效

$str = "-test aa_aa     -machine  aab-baa-aba  -from ccc";
($test,$machine,$from) = $str =~ /\-test(.+)\-machine(.+)\-from(.+)/;

print "Test: $test, Machine: $machine, From: $from";

这将适用于您的测试数据:
perl-e'use strict;使用警告;my$str=“-测试aaaa-机器bbb-来自ccc”;虽然($str=~m/(\w+)/g){print$1.“\n”;}”
非常感谢…但是如果数据中有一些符号,比如“-test aa_aa-machine aab baa aba-from ccc”。如何正确获取数据?感谢您的回复字符串中
-test
-machine
-form
的顺序可能会更改(如问题中所述),在这种情况下,您的解决方案将无法工作。此外,您还可以使用
+
捕获空白,这并不理想。如果要添加一个额外的参数,它将被捕获为前一个参数之一的值。另外,没有必要在正则表达式中转义
-
(有时在
[…]
中除外。谢谢。我从来没有想过“拆分”。这是一个很好的选择=)
$str =~ /-test\s*(\S*)\s*/;
$str = "-test aa_aa     -machine  aab-baa-aba  -from ccc";
($test,$machine,$from) = $str =~ /\-test(.+)\-machine(.+)\-from(.+)/;

print "Test: $test, Machine: $machine, From: $from";