好的,我要编写一个简单的 Perl 5 脚本,它打印出以 D 开头并以 E 结尾的单词...
$_ = "Dog Die Do Dome";
/^d.*e$/i;
如图所示,我使用正则表达式搜索我的文本以找到这样的单词,但我如何打印出来呢?提前感谢您的帮助。
/g
您可以使用修饰符捕获到数组。
use feature 'say';
my @words = /\bd\S+e\b/ig;
say for @words;
在列表上下文中,这将返回所有以“d”开头并以“e”结尾的匹配项。请注意,您不能使用.*
,因为该匹配是贪婪的,因此"dog do die"
将返回具有贪婪匹配的整个字符串dog do die
,而不仅仅是"die"
. 使用单词边界\b
会阻止您部分匹配,例如 with foobaresk
。
首先是您的正则表达式正在捕获您的整个字符串。正则表达式通常是贪婪的,因此.*
将匹配字符串中最长的部分。由于您的正则表达式以 a 开头并以 ad
结尾e
,因此它将匹配您的整个字符串。
有几种方法可以避免这种情况:
my $string = "Dog Die Do Dome";
my $string =~ /d[\S]+e/ig;
由于\S
说no white space,因此您只匹配以 a 开头D
和以 an 结尾E
且不包含空格的单词。因此,它现在将单独匹配Die
and Dome
,但不匹配Dog
and Do
。这是正则表达式中的常见技巧。例如,您有一个字符串foo-bar-bam
,并且只想匹配第一个单词。使用/[^-][^-]*/
会解决问题(请记住,它*
可以代表前面的零个或多个。因此,您将它加倍以匹配至少一个。)。这主要用于旧版本的grep或sed,您没有 Perl 的扩展正则表达式的强大功能。在上面的示例中,我使用+
了*
因为+
意味着匹配前面的一个或多个。
*
Perl 还可以通过在or后面附加一个问号来使正则表达式不贪婪+
:
my $string =~ /d.+?e/ig;
但是,在您的情况下,这将匹配Dog Die
,Dome
这可能不是您想要的。
这是程序:
use strict;
use warnings;
use feature qw(say);
my $string = "Dog Die Do Dome";
my @matches = ($string =~ /D\S+e/gi);
for my $word (@matches) {
say "The first match is $word";
}
并且,它打印出:
The first match is Die
The first match is Dome
好吧,也许我不应该使用The first match
,但你明白了。试试这个带有各种正则表达式的示例程序,看看会发生什么。
>cat temp
Dog Die Do Dome
>perl -lne '@a=split" ";foreach(@a){print if(/^[dD].*[eE]$/)}' temp
Die
Dome
1
2 my $word_list = "Dog Die Do Dome";
3 my @words = split ' ', $word_list;
4 for my $word (@words) {
5 print "$word\n" if $word =~ /^d.*e$/i;
6 }
~
~
~
~