Reputation: 567
Ok, I'm going a simple Perl 5 Script that prints out words that begin with D and end with E...
$_ = "Dog Die Do Dome";
/^d.*e$/i;
As shown, I used Regular Expressions to search through my text to find such words, but how to I print them out? Thank in advance for any help.
Upvotes: 0
Views: 154
Reputation: 67211
>cat temp
Dog Die Do Dome
>perl -lne '@a=split" ";foreach(@a){print if(/^[dD].*[eE]$/)}' temp
Die
Dome
Upvotes: 1
Reputation: 107040
First thing is that your regular expression is capturing your entire string. Regular expressions are normally greedy, so the .*
will match the longest part of the string that's true. Since your regular expression begins with a d
and ends with an e
, it will match your whole string.
There are several ways you could avoid this:
my $string = "Dog Die Do Dome";
my $string =~ /d[\S]+e/ig;
Since \S
says no white space, you are only matching the words that begin with a D
and end with an E
and contain no white space. Thus, it will now match Die
and Dome
separately, but not Dog
and Do
. This is a common trick in regular expressions. For example, you have a string foo-bar-bam
, and only want to match the first word. Using /[^-][^-]*/
will do the trick (remember that *
can stand for zero or more of the preceding. Thus, you double it up to match at least one.). This is mainly used in older versions of grep or sed where you don't have the power of Perl's expanded regualar expressions. In my example above, I used +
instead of *
because +
means match one or more of the preceding.
Perl also has a way to make a Regular expression non-greedy by using appending a question mark after the *
or +
:
my $string =~ /d.+?e/ig;
However, in your case, this would match Dog Die
and Dome
which is probably not what you want.
Here's the program:
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";
}
And, it prints out:
The first match is Die
The first match is Dome
Okay, maybe I shouldn't use The first match
, but you get the idea. Try this sample program with various regular expressions and see what happens.
Upvotes: 2
Reputation: 6543
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 }
~
~
~
~
Upvotes: 0
Reputation: 67900
You can capture to an array, using the /g
modifier.
use feature 'say';
my @words = /\bd\S+e\b/ig;
say for @words;
In list context, this will return all matches which start with a "d" and ends with an "e". Note that you cannot use .*
because that match is greedy, so "dog do die"
will return the entire string dog do die
with a greedy match, and not just "die"
. Using the word boundary \b
will prevent you from matching partially, such as with foobaresk
.
Upvotes: 4
Reputation: 84343
print
StatementYou use the print statement to send output to the screen. Since you are matching entire lines, you don't have to do anything complex here; you can just use the implied $_ variable. For example:
print if /^d.*e$/i
Upvotes: 1