I'm trying to write a short script in Perl to go through a an array of strings provided by the user, check in a hash table to see if there are vowels in the strings, then return the strings minus the vowels. I know this would be easier to accomplish using regex, but the parameters for the problem state that a hash table, exists()
, and split()
must be used. This is the script I have so far:
my @vowels = qw(a e i o u A E I O U);
my %vowel;
foreach $v (@vowels) {
$vowel{$v} = undef;
}
foreach $word (@ARGV) {
my @letter_array = split(undef,$word);
}
foreach $letter (@letter_array) {
print($letter) if !exists($vowel{$letter})
}
print "\n"
Input: hello
Expected output: hll
Actual output: nothing
There are no error messages, so I know it's not a syntax error. Any ideas what I'm messing up? I'm much more comfortable with Python and this is one of my first attempts at Perl.
You should use strict
not to mess visibility of your variables. If you require perl version 5.12
or higher it would be used automatically.
So your list @letter_array
exists only in foreach my $word (@ARGV)
loop. That's why it's empty in the end.
If you want to fix that you'll get the following code:
#!/usr/bin/env perl
use strict;
use warnings;
my @vowels = qw( a e i o u y A E I O U Y );
my %vowel;
foreach my $v (@vowels) {
$vowel{$v} = undef;
}
my @letter_array;
foreach my $word (@ARGV) {
@letter_array = split //, $word;
}
foreach my $letter (@letter_array) {
print($letter) if !exists($vowel{$letter})
}
print "\n"
But this code is still not practical.
map
to get the hash of vowels much easier without using extra variables.unless
if you want to check if not
to make it prettier and more perl-style.split //, $word
for
instead of foreach
because it's the same but shorter:)So you can get an optimised solution.
#!/usr/bin/env perl
use 5.012;
use warnings;
my %vowels = map { $_ => undef } qw( a e i o u y A E I O U Y );
for my $word (@ARGV) {
my @letters = split //, $word;
for my $letter (@letters) {
print $letter unless exists $vowels{$letter};
}
print ' ';
}
print "\n"
Result:
$ perl delete_vowels.pl hello world
hll wrld
An alternative and more compact method of achieving the same thing is to use the substitute operator, " s " with a regular expression that matches the vowels.
Here is an example
use strict;
use warnings;
for my $word (@ARGV)
{
print $word =~ s/[aeiou]//gri;
}
or more succinctly like this
use strict;
use warnings;
for (@ARGV)
{
print s/[aeiou]//gri;
}
Key points to note
[aeiou]
to match a single lower-case vowel.i
option to force a case insensitive match. This means the Character Class [aeiou]
will match both uppercase and lower-case vowels.g
option to make the substitute match all instances of the regular expression -- in this instance it will match against all the vowels in the string. r
option (which is a newish addition to Perl) to get the substitute operator to return the substituted string. running that gives this
$ perl try.pl hello world
hllwrld
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.