给出一个短语,例如“我正在搜索文本”和一个包含单词列表的文本文件。
我必须找到文本文件中是否存在单词的每个组合。
例如,我必须搜索“我”,“我是”,“我正在搜索”,“我正在搜索”,“搜索”等事件。
我更喜欢用perl编写这个,我需要一个运行得更快的最佳解决方案。
示例文本文件:
I \n
am searching \n
Text \n
searching for \n
searching for a \n
for searching ---> my program should not match this
etc
答案 0 :(得分:1)
下面的代码打印了您要匹配的所有子词。
$phrase = 'I am searching for a text';
$\ = "\n";
@words = ();
print "Indices:";
while( $phrase =~ /\b\w+\b/g ) {
push @words, {word => $&, begin => $-[0], end => $+[0]};
}
$num_words = $#words + 1;
print 'there are ', $num_words, ' words';
for( $i=0; $i<$num_words; $i++ ) {
for( $j=$i; $j<$num_words; $j++ ) {
($start,$finish) = ($words[$i]->{begin}, $words[$j]->{end});
$sub_phrase = substr $phrase, $start, $finish-$start;
print "$i-$j: $sub_phrase";
}
}
一些解释:
要完成练习,您需要将所有sub_phrase保存到一个数组中(而不是&#39; print&#39; do&#39; push&#39; into @permutations)。然后迭代你的文本文件,对于每一行,尝试匹配每个排列。
答案 1 :(得分:1)
您可以构造一个适用于所有这些情况的表达式。下面,我将展示如何在Perl中构建构建(尽管您可以将产品用于您的目的)。
use List::Util qw<reduce>;
our ( $a, $b );
my $regex
= "\n^\n( "
. join( "\n| "
, @{( reduce {
my $r = ref( $a ) ? $a : [ "$a " ];
my $s = $r->[0];
[ "$b (?> [ ] $s)?", @$r ]
}
reverse split ' ', 'I am searching for a text'
)}
)
. "\n)\n\\s*\n\$"
;
say join( "\n# ", split "\n", $regex );
# ^
# ( I (?> [ ] am (?> [ ] searching (?> [ ] for (?> [ ] a (?> [ ] text )?)?)?)?)?
# | am (?> [ ] searching (?> [ ] for (?> [ ] a (?> [ ] text )?)?)?)?
# | searching (?> [ ] for (?> [ ] a (?> [ ] text )?)?)?
# | for (?> [ ] a (?> [ ] text )?)?
# | a (?> [ ] text )?
# | text
# )
# \s*
# $
map { say foreach m/$regex/xo } <DATA>;
/x
来忽略它们。这就是我们用[ ]
指定空间的原因。 (?>...)
是非捕获(?:...)
的变体,但失败的速度要快很多。请参阅http://perldoc.perl.org/perlre.html#(%3f%3epattern) List::Util::reduce