我有以下代码:
my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ m/^(\w)*\:(\w*)\_em\.$/)
{
print "$1\:$2\.\n";
}
else
{
print "$1\:$2\_em\.\n";
}
但我变空$1
和$2
。输出是:
Use of uninitialized value in concatenation (.) or string at new_mscn_iden_parse.pl line 187.
Use of uninitialized value in concatenation (.) or string at new_mscn_iden_parse.pl line 187.
:_em.
答案 0 :(得分:4)
此代码将执行您想要的操作
my $sDatabase = "abc_def:xyz_comp.";
$sDatabase =~ m/^(\w+):(\w+?)(_em)?\.$/ or die "Invalid data";
if ($3) {
print "$1:$2.\n";
}
else {
print "$1:$2_em.\n";
}
答案 1 :(得分:3)
当您未能匹配时,您希望$1
和$2
包含哪些内容?!
它包含尝试匹配前包含的内容。
可能的解决方案:
$sDatabase =~ s/(?<!_em)(?=\.\z)/_em/;
答案 2 :(得分:1)
你有:
my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ m/^(\w)*\:(\w*)\_em\.$/);
让我们看看这是否匹配:
你是正常的表达说:
/\w*/
将匹配以下所有内容:_em
字符串现在,让我们看一下你的字符串:abc_def:xyz_comp.
\w*
将匹配abc_def
。正则表达式是贪婪的,并且会尽可能地匹配字符串的最大部分。:
将匹配冒号。到目前为止,您正在匹配abc_def:
。\w*
将匹配xyz_comp
。_em
。哎呀!不好。您的字符串中没有_em
。您的正则表达式匹配将失败。由于正则表达式匹配失败,$1
和$2
变量根本没有设置且没有值。
这就是你获得Use of uninitialized value
的原因。您可以做的是使表达式的后半部分可选:
my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ /^(\w)+:(\w*)(_em)?\.$/) {
if ( $3 ) {
print "$1:${2}${3}.\n";
else {
print "$1:${2}_em.";
}
}
else {
die qq(String doesn't match regular expression at all\n);
}
}
首先,我认为你想要匹配至少一个字符(我可能是错的),所以我将匹配零或更多的星号切换为匹配的+
一个或多个。
注意我有第三组括号后跟?
。这意味着匹配此零或一个次。因此,您将匹配,只要您的字符串以一个或多个单词字符开头,后跟冒号,后跟一个或多个单词字符,就会设置$1
和$2
。< / p>
不一定会发生$3
的设定。只有在您的字符串也以_em.
结尾时才会设置此项。如果您的字符串不包含_em
,但以句点结尾,$1
和$2
仍会匹配。
在您的情况下,我们可以通过这样做来简化它:
my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ /^(\w)+:(\w*)(?:_em)?\.$/) {
print "$1:${2}_em.";
else {
die qq(String doesn't match regular expression at all\n);
}
(?:...)
表示不设置匹配,只设置组。因此,永远不会设置$3
。没关系,要么$ 3是_em.
,要么我们在比赛结束时添加_em.
。