我正在Perl和正则表达式中研究chet-bot程序,但是我没有得到预期的结果,因为您看到我的哈希中有所有代词和动词,并且我遍历字符串,如果它与哈希键匹配,则将其替换为哈希键值当前的子字符串值。
程序输出
Eliza:嗨,我是心理治疗师。你叫什么名字?
亚当:我叫亚当
Eliza:亚当你好,你好吗?
亚当:我感到不舒服
Eliza:为什么您会感到不适?
亚当:,因为我生病了
Eliza:为什么会生病?
不管最后一个问题中的“因为”一词,但输出应该是这样的
Eliza:为什么因为您生病了?
关于如何解决此问题的任何建议。
代码:
sub makeQuestion{
my ($patient) = @_;
my %reflections = (
"am" => "are ",
"was" => "were ",
"i" => "you ",
"i'd" => "you would ",
"i've" => "you have ",
"i'll" => "you will ",
"my" => "your ",
"are" => "am ",
"you've"=> "I have ",
"you'll"=> "I will ",
"your" => "my ",
"yours" => "mine ",
"you" => "me ",
"me" => "you "
);
my @toBes = keys %reflections;
foreach my $toBe (@toBes) {
if ($patient =~/$toBe\b/)
{
$patient=~ s/$toBe /$reflections{$toBe}/i;
}
}
print "Why $patient? \n";
}
最佳答案
编辑:如@zdin所建议,我将'\s'
替换为' '
,它将匹配任意数量的空格,并且也忽略前导空格。
那是因为您要遍历%reflections哈希的完整键并进行系统替换。因此,您在循环1中找到“am”键,并将其替换为“are”。然后,您在循环8中找到“are”键,并将其替换为“am”。
在替换单个单词时,您应该使用split来确保只对单个单词运行一次:
#!/usr/bin/perl
use strict;
use warnings;
my $question = '';
while ($question ne 'stop') {
$question = <STDIN>;
chomp $question;
print makeQuestion($question)."\n";
}
sub makeQuestion{
my ($patient) = @_;
my @new_question;
my %reflections = (
"am" => "are",
"was" => "were",
"i" => "you",
"i'd" => "you would",
"i've" => "you have",
"i'll" => "you will",
"my" => "your",
"are" => "am",
"you've"=> "I have",
"you'll"=> "I will",
"your" => "my",
"yours" => "mine",
"you" => "me",
"me" => "you",
);
WORDS: foreach my $word (split ' ', $patient) {
REPLACE: foreach my $key (keys %reflections) {
if ($word =~ m{\A$key\Z}i) {
$word =~ s{$key}{$reflections{$key}}i;
last REPLACE;
}
}
push @new_question, $word;
}
return join ' ', @new_question;
}
关于perl - 模式匹配和Perl中的正则表达式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42018775/