我有以下正则表达式,它在PERL中用于查找单词的开头是否包含在字符串中。我希望可以找到 divo ,但不能潜水。这对蛮力来说并不算太糟糕。
if ($a =~ /\b(div|divo|divor|divorc|divorce|divorces)\b/i)
{
print "OK, I found the substring I needed.";
}
换句话说,如果我的程序在字符串中看到“离婚”的开始,它会将该字符串标记为我想要查看的内容。
如果我想这样做一次就可以了,但我有理由多次用多次这样做。
有没有办法只使用正则表达式,或者我必须做类似的事情:
use strict;
use warnings;
while (my $str = <STDIN>)
{
if (mymatch($str, "divorces", 3, 8))
{
print "Yay!\n";
}
}
sub mymatch
{
my $temp;
for ($_[2]..$_[3])
{
$temp = substr($_[1], 0, $_);
if ($_[0] =~ /\b$temp\b/i)
{
return 1;
}
}
return 0;
}
虽然能够使用上述功能是可以接受的,但我有一种感觉,我错过了一个强大的高级正则表达式,可能对我将来也有帮助。
感谢您对此提供的任何帮助!
答案 0 :(得分:2)
如果你把事情弄清楚,这会更容易。而不是
"divo settlement talks" =~ /\b(div|divo|divor|divorc|divorce|divorces)\b/i
让我们做
"divorced" =~ /^(?:divo|settlement|talks)/i
代码:
sub mymatch {
my ($str, $targ, $min) = @_;
my $max = length($targ);
for my $word (grep { length($_) >= $min && length($_) <= $max } $str =~ /\w+/g) {
return 1 if $targ =~ /^$word/i;
}
return 0;
}
或
sub mymatch {
my ($str, $targ, $min) = @_;
my $max = length($targ);
for my $word ($str =~ /\b\w{$min,$max}\b/g) {
return 1 if $targ =~ /^$word/i;
}
return 0;
}
或
sub mymatch {
my ($str, $targ, $min) = @_;
my $max = length($targ);
my $pat = '^(?:' . join('|', $str =~ /\b\w{$min,$max}\b/g) . ')';
return $targ =~ /$pat/i;
}
你的方式,虽然更复杂,但具有构建正则表达式的优势,可以搜索大量文本,甚至可以同时搜索多个单词。
sub build_pattern {
my $min = shift;
my @targs;
for my $targ (@_) {
push @targs, map { substr($targ, 0, $_) } $min..length($targ);
}
my $pat = join('|', @targs);
return qr/\b(?:$pat)\b/i;
}
my $re = build_pattern(3, qw( divorced ... ));
$str =~ $re
答案 1 :(得分:1)
您已了解正则表达式中的单词边界。因此,尝试将文本拆分为单词:
my $text = "The case took a dive when the two parties divided over division of assets in the divorce.";
my @text_words = split(/\s+/, $text);
现在对你感兴趣的关键词进行(设定)哈希:
my %key_words = map { $_ => 1 } qq(div divo divor divorc divorce divorces);
寻找另一个:
foreach my $word (@text_words) {
if (exists $key_words{$word}) {
# Your code goes here.
print "OK, I found the substring I needed.";
}
}
这样做的好处是,您可以与您可能感兴趣的其他单词/前缀合并,并同时搜索所有单词/前缀。