是否存在用于匹配单词的第一个(x到y)字符的非强制正则表达式?

时间:2017-03-31 00:56:47

标签: regex perl

我有以下正则表达式,它在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;
}

虽然能够使用上述功能是可以接受的,但我有一种感觉,我错过了一个强大的高级正则表达式,可能对我将来也有帮助。

感谢您对此提供的任何帮助!

2 个答案:

答案 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.";
    }
}

这样做的好处是,您可以与您可能感兴趣的其他单词/前缀合并,并同时搜索所有单词/前缀。