Pr0*_*0no 3 php regex performance suffix-tree string-matching
维基百科定义了人们可以使用的许多可能的表情符号。我想将此列表与字符串中的单词匹配。我现在有这个:
$string = "Lorem ipsum :-) dolor :-| samet";
$emoticons = array(
'[HAPPY]' => array(' :-) ', ' :) ', ' :o) '), //etc...
'[SAD]' => array(' :-( ', ' :( ', ' :-| ')
);
foreach ($emoticons as $emotion => $icons) {
$string = str_replace($icons, " $emotion ", $string);
}
echo $string;
Run Code Online (Sandbox Code Playgroud)
输出:
Lorem ipsum [HAPPY] dolor [SAD] samet
Run Code Online (Sandbox Code Playgroud)
所以原则上这是有效的。但是,我有两个问题:
如您所见,我在数组中的每个表情符号周围放置了空格,例如 ':-) ' 而不是 ':-)' 在我看来,这使得数组的可读性降低。有没有办法在没有空格的情况下存储表情符号,但仍然与周围有空格的 $string 匹配?(和现在的代码一样高效?)
或者有没有办法将表情符号放在一个变量中,然后在空间上爆炸以检查 $string?就像是
$emoticons = array( '[HAPPY]' => ">:] :-) :) :o) :] :3 :c) :> =] 8) =) :} :^)", '[SAD] ' => ":'-( :'( :'-) :')" //等等...
str_replace 是最有效的方法吗?
我问是因为我需要检查数百万个字符串,所以我正在寻找节省处理时间的最有效方法:)
这是使用来自 CPAN的 Perl 3rd-party Regexp::Assemble模块的想法。例如,给定这个程序:
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
use Regexp::Assemble;
my %faces = (
HAPPY => [qw¡ :-) :) :o) :-} ;-} :-> ;-} ¡],
SAD => [qw¡ :-( :( :-| ;-) ;-( ;-< |-{ ¡],
);
for my $name (sort keys %faces) {
my $ra = Regexp::Assemble->new();
for my $face (@{ $faces{$name} }) {
$ra->add(quotemeta($face));
}
printf "%-12s => %s\n", "[$name]", $ra->re;
}
Run Code Online (Sandbox Code Playgroud)
它会输出这个:
[HAPPY] => (?-xism:(?::(?:-(?:[)>]|\})|o?\))|;-\}))
[SAD] => (?-xism:(?::(?:-(?:\||\()|\()|;-[()<]|\|-\{))
Run Code Online (Sandbox Code Playgroud)
那里有一些您可能并不真正需要的额外内容,因此这些内容将减少为:
[HAPPY] => (?:-(?:[)>]|\})|o?\))|;-\}
[SAD] => (?:-(?:\||\()|\()|;-[()<]|\|-\{
Run Code Online (Sandbox Code Playgroud)
或者。您可以将其构建到 Perl 程序中以修剪额外的位。然后您可以将右侧直接放入您的preg_replace.
我这样做的原因use utf8是我可以¡用作我的qw//分隔符,因为我不想在里面转义东西。
如果整个程序都在 Perl 中,您就不需要这样做,因为现代版本的 Perl 已经知道会自动为您执行此操作。但是了解如何使用该模块仍然很有用,这样您就可以生成在其他语言中使用的模式。