以下perl脚本和TestData模拟了我只能找到2而不是4个预期的情况。 (以匹配所有support.tier.1与中间的反斜杠。)
如何在此处修改此perl正则表达式?感谢
my @TestData(
"support.tier.1",
"support.tier.2",
qw("support\.tier\.1"),
"support\.tier\.2",
quotemeta("support.tier.1\@example.com"),
"support.tier.2\@example.com",
"support\.tier\.1\@example\.com",
"support\.tier\.2\@example\.com",
"sales\@example\.com"
);
以下是要更改的代码:
my $count = 0;
foreach my $tier(@TestData){
if($tier =~ m/support.tier.1/){
print "$count: $tier\n";
}
$count++;
}
我只得到2场比赛,而预期的是4场比赛:
0: support.tier.1
6: support.tier.1@example.com
答案 0 :(得分:3)
由于您似乎确实可以获得包含反斜杠的字符串,因此我建议您在测试字符串之前使用String::Unescape
删除这些反斜杠。您可能必须安装它,因为它不是核心模块
您的代码看起来像这样
use strict;
use warnings;
use String::Unescape;
my @tiers = (
"support.tier.1",
"support.tier.2",
qw("support\.tier\.1"),
"support\.tier\.2",
quotemeta("support.tier.1\@example.com"),
"support.tier.2\@example.com",
"support\.tier\.1\@example\.com",
"support\.tier\.2\@example\.com",
"sales\@example\.com",
);
my $count = 0;
for my $tier ( @tiers ) {
my $plain = String::Unescape->unescape($tier);
if ( $plain =~ /support\.tier\.1/ ) {
printf "%d: %s\n", ++$count, $tier;
}
}
1: support.tier.1
2: "support\.tier\.1"
3: support\.tier\.1\@example\.com
4: support.tier.1@example.com
请注意,String::Unescape
模块中存在一个错误,导致其无法导出unescape
功能。这只是意味着您必须始终使用String::Unescape::unescape
或String::Unescape->unescape
。或者您可以使用*unescape = \&String::Unescape::unescape
@tiers
数组包含这些确切的字符串
support.tier.1
support.tier.2
"support\.tier\.1"
support.tier.2
support\.tier\.1\@example\.com
support.tier.2@example.com
support.tier.1@example.com
support.tier.2@example.com
sales@example.com
你能看到只有第1和第7项包含字符串support.tier.1
吗?我想你想要匹配的另外两个是3和5,其中包含虚假的反斜杠
目前尚不清楚,但您似乎不太可能以此格式获取数据。如果你真的想匹配support.tier.1
,其中任何一个点前面都有一个反斜杠字符,那么你需要/support\\?\.tier\\?\.1/
,但我认为你误解了Perl字符串的工作方式
答案 1 :(得分:2)
我可能不完全明白,但如果我这样做,我同意马特已经试图给你的答案。如果您在support.tier.1
中的每个句点之前说出转义字符可能会或可能不会出现,那么正则表达式肯定可以处理您的请求。
单个反斜杠为\\
,?
表示“一个或零”:
use strict;
use warnings;
my @tiers = (
"support.tier.1",
"support.tier.2",
qw("support\.tier\.1"),
"support\.tier\.2",
quotemeta("support.tier.1\@example.com"),
"support.tier.2\@example.com",
"support\.tier\.1\@example\.com",
"support\.tier\.2\@example\.com",
"sales\@example\.com",
);
my $count = 0;
foreach my $tier (@tiers) {
if ($tier =~ /support\\?.tier\\?.1/) {
print "$count: $tier\n";
}
$count++;
}
在一个不相关的说明中,为了创建一个易于理解的示例,我提供了一个建议,说明如何更好地格式化示例数据,而不是使用$str
和push
es
如果有效,我建议你让马特发表评论回复作为答案并接受。