我有一个我需要解析的字符串。它符合以下要求:
我可能会看到示例字符串:
我需要构建此字符串的Perl哈希值。如果我能保证它是1对,我会做这样的事情:
$string =~ /([A-Z][A-Z])([0-9]+)/
$key = $1
$value = $2
$hash{$key} = $value
对于多个字符串,我可以做一些事情,在上述正则表达式的每次匹配之后,我获取原始字符串的子字符串(免除第一个匹配),然后再次搜索。但是,我确信有一种更聪明,更为方便的方式来实现这一目标。
希望我没有这么糟糕的数据源来处理 -
乔纳森
答案 0 :(得分:8)
在带有全局标志的列表上下文中,正则表达式将返回all matched substrings:
use Data::Dumper;
@strs = (
'AB1234',
'AB1234 BC2345',
'AB1234BC2345',
'',
'AB12345601BC1234CD1232PE2343',
'AB12345601 BC1234 CD1232 PE2343'
);
for $str (@strs) {
# The money line
%parts = ($str =~ /([A-Z][A-Z])(\d+)/g);
print Dumper(\%parts);
}
要获得更高的不透明度,请删除模式匹配周围的括号:%parts = $str =~ /([A-Z][A-Z])(\d+)/g;
。
答案 1 :(得分:3)
你已经在那里了:
$hash{$1} = $2 while $string =~ /([[:alpha:]]{2})([0-9]+)/g
答案 2 :(得分:0)
假设您的字符串绝对符合您的方案(即不会有A122
或ABC123
形式的任何字符串,那么这应该有效:
my @strings = ( 'AB1234', 'AB1234 BC2345', 'AB1234BC2345' );
foreach my $string (@strings) {
$string =~ s/\s+//g;
my ( $first, %elems ) = split(/([A-Z]{2})/, $string);
while (my ($key,$value) = each %elems) {
delete $elems{$key} unless $key =~ /^[A-Z]{2}$/;
delete $elems{$key} unless $value =~ /^\d{4}$/;
}
print Dumper \%elems;
}