我是Perl的新手。我有一个编写Perl程序的任务,该程序接受来自命令行的可数字,然后生成其复数形式。我在下面编写了以下代码,它没有显示编译错误。当我从命令行执行它时: (perl plural.pl,例如),它提示我输入一个名词,然后我输入的任何名词作为输入,复数形式是相同的。它不执行剩余的if语句。
例如,如果我输入单词“cat”,则复数形成为“cats”。但是当我输入“教堂”这个词时,复数就会产生“教堂”,“飞”就像“飞翔”。
以下是代码:
#!/usr/bin/perl
$suffix1 = 's';
$suffix2 = 'es';
$suffix3 = 'ies';
print "Enter a countable noun to get plural: ";
$word = <STDIN>;
chomp($word);
if(substr $word, -1 == 'b' or 'd' or 'c' or 'g' or 'r' or 'j' or 'k' or 'l' or 'm' or 'n' or 'p' or 'q' or 'r' or 't' or 'v' or 'w' or 'e' or 'i' or 'o' or 'u') {
$temp = $word.$suffix1;
print "The plural form of the word \"$word\" is: $temp \n";
}
elsif (substr $word, -1 == 's' or 'sh' or 'ch' or 'x' or 'z') {
$temp = $word.$suffix2;
print "The plural form of the word \"$word\" is: $temp \n";
}
elsif (substr $word, -1 == 'y') {
chop($word);
$temp = $word.$suffix3;
print "The plural form of the word \"$word\" is: $temp \n";
}
你能帮助我让代码执行三个语句。
答案 0 :(得分:8)
首先,始终使用use strict; use warnings;
。
使用eq
而非==
比较字符串。
substr $word, -1 eq 'b'
时, substr $word, (-1 eq 'b')
表示substr($word, -1) eq 'b'
。如果省略函数调用的问题,你将面临很多问题。
substr($word, -1) eq 'b' or 'd'
表示与(substr($word, -1) eq 'b') or ('d')
相同。 'd'
总是如此。您需要使用substr($word, -1) eq 'b' or substr($word, -1) eq 'd'
。 (最好将substr $word, -1
保存在变量中以避免重复执行。)
substr $word, -1
永远不会等于ch
或sh
。
匹配运算符使这很容易:
if ($word =~ /[bdcgrjklmnpqrtvweiou]\z/) {
...
}
elsif ($word =~ /(?:[sxz]|[sc]h)\z/) {
...
}
elsif ($word =~ /y\z/) {
...
}
答案 1 :(得分:3)
eq
进行字符串比较,而不是==
。or
。它应该像if (substr($word, -1) eq 'b' or substr ($word, -1) eq 'd')
。否则,您可以使用一个数组,其中包含您要比较的所有字符串以及该数组中的grep。答案 2 :(得分:2)
Duskast是对的。 Perl使用符号进行数字比较,使用字符串进行字符串比较。
== eq
!= ne
< lt
<= le
> gt
>= ge
<=> cmp
此外,您使用or
虽然是一次不错的尝试但不起作用。关键字or
的优先级较弱,因此表达式
substr $word, -1 == 'b' or 'd' or 'c' or
'g' or 'r' or 'j' or
'k' or 'l' or 'm' or
'n' or 'p' or 'q' or
'r' or 't' or 'v' or
'w' or 'e' or 'i' or
'o' or 'u'
被解释为
substr ($word, (-1 == 'b')) or 'd' or 'c' or
'g' or 'r' or 'j' or
'k' or 'l' or 'm' or
'n' or 'p' or 'q' or
'r' or 't' or 'v' or
'w' or 'e' or 'i' or
'o' or 'u'
我不确定substr的作用是什么,但如果它是假的,则表达式继续到or 'b'
,这被解释为true
。你看过正则表达了吗?
if ($word =~ /[bdcgrjklmnpqrtvweiou]$/) {...}
# Does $word match any of those characters followed by
# the end of the line or string?
在Perl文档中查找字符串替换和s /.../.../构造。
顺便说一下,如果你是这样做的而不是学生,你就会使用Lingua模块。
答案 3 :(得分:2)
首先,始终包括use strict;
和use warnings;
。
其次,使用缩进。我在工作中教过Perl课程并且拒绝接受任何没有正确缩进的作业。事实上,我对此非常非常严格,因为我希望用户学会编写标准代码(4个空格缩进等)。它使您的程序更易于阅读和支持。
虽然我们正在努力,但要打破过长的行 - 特别是在StackOverflow上。当你必须来回滚动时,很难阅读一个程序。
快速查看您的计划:
在Perl中,字符串和数字使用两组不同的布尔运算。这是因为字符串只能包含数字,但仍然是字符串。想象一下库存项目编号,例如1384
和993
。如果我将它们排序为字符串,则1384
项首先出现。如果我在数字上对它们进行排序,993
应该首先出现。除了你使用的布尔操作外,你的程序无法知道这个:
Boolean Operation Numeric String
================= ======= ======
Equals == eq
Not Equals != ne
Greater Than > gt
Less Than < lt
Greater than/Equals >= ge
Less than/Equals <= le
另一个是or
,and
,||
和&&
仅适用于两个布尔值。这不起作用:
if ( $a > $b or $c ) {
这说的是:
if ( ( $a > $b ) or $c ) {
因此,如果$c
为非零值,则$c
将为 true ,整个语句将为true。你必须这样做你的陈述:
if ( $a > $b or $a > $c ) {
另一方面,在引用包含引号的字符串时使用qq(..)
和q()
。这样,您就不必在它们前面加上反斜杠。
print "The word is \"swordfish\"\n";
print qq(The word is "swordfish"\n);
并且,如果您在程序的顶部使用use feature qw(say);
,则会获得say
的奖励命令,类似于print
,除了假定结束的新行:
say qq(The word is "swordfish");
当您使用substr, $foo, -1
时,您只会查看最后一个字符。它不能是两个字符串:
if ( substr $word, -1 eq "ch" ) {
总是假的。
很长时间难以维持。我会使用for loop
(实际上不是,但让我们假装现在......):
#! /usr/bin/env perl
#
# Use these in ALL of your programs
#
use strict;
use warnings;
use feature qw(say);
#
# Use better, more descriptive names
#
my $standard_plural_suffix = 's';
my $uncommon_plural_suffix = 'es';
my $y_ending_plural_suffix = 'ies';
print "Enter a countable noun to get plural: ";
chomp (my $word = <STDIN>);
my $plural_form;
#
# Instead of a long, long "if", use a for loop for testing. Easier to maintain
#
for my $last_letter qw( b d c g r j k l m n p q r t v w e i o u) {
if ( substr($word, -1) eq $last_letter ) {
$plural_form = $word . $standard_plural_suffix;
last;
}
}
#
# Is it an "uncommon plural" test (single character)
#
if ( not $plural_form ) {
for my $last_letter qw(s x z) {
if ( substr($word, -1) eq $last_letter ) {
$plural_form = $word . $uncommon_plural_suffix;
last;
}
}
}
#
# Is it an "uncommon plural" test (double character)
#
if ( not $plural_form ) {
for my $last_two_letters qw(sh ch) {
if ( substr($word, -2) eq $last_two_letters ) {
$plural_form = $word . $uncommon_plural_suffix;
last;
}
}
}
if ( not $plural_form ) {
if ( substr($word, -1) eq 'y' ) {
chop ( my $chopped_word = $word );
$plural_form = $chopped_word . $y_ending_plural_suffix;
}
}
if ( $plural_form ) {
say qq(The plural of "$word" is "$plural_form");
}
else {
say qq(Could not find plural form of "$word");
}
你知道正则表达式吗?这些比使用substr
要好得多,因为你可以一次测试多个东西。另外,我不会使用chop
,而是使用正则表达式替换:
#! /usr/bin/env perl
#
# Use these in ALL of your programs
#
use strict;
use warnings;
use feature qw(say);
#
# Use better, more descriptive names
#
my $standard_plural_suffix = 's';
my $uncommon_plural_suffix = 'es';
my $y_ending_plural_suffix = 'ies';
print "Enter a countable noun to get plural: ";
chomp (my $word = <STDIN>);
my $plural_form;
#
# Standard plural (adding plain ol' 's'
#
if ( $word =~ /[bdcgrjklmnpqrtvweiou]$/ ) {
$plural_form = $word . $standard_plural_suffix;
}
#
# Uncommon plural (adding es)
#
elsif ( $word =~ /([sxz]|[sc]h)$/ ) {
$plural_form = $word . $uncommon_plural_suffix;
}
#
# Final 'y' rule: Replace y with ies
#
elsif ( $word =~ /y$/ ) {
$plural_form = $word;
$plural_form =~ s/y$/ies/;
}
if ( $plural_form ) {
say qq(The plural of "$word" is "$plural_form");
}
else {
say qq(Could not find plural form of "$word");
}
答案 4 :(得分:0)
我已经改变了你的代码。我正在使用正则表达式:
#!/usr/bin/perl
$suffix1 = 's';
$suffix2 = 'es';
$suffix3 = 'ies';
print "Enter a countable noun to get plural: ";
$word = <STDIN>;
chomp($word);
if ( $word =~ m/(s|sh|ch|x|z)$/) {
$temp = $word . $suffix2;
}
elsif ( substr( $word, -1 ) eq 'y' ) {
chop($word);
$temp = $word . $suffix3;
}
else {
$temp = $word . $suffix1;
}
print "The plural form of the word \"$word\" is: $temp \n";
另外,我建议您始终use strict;
和use warnings;