除了 Perl,我不知道有任何正则表达式引擎可以进行调试。
因此,作为类比,我使用 Perl 示例代码来展示如何节省大量时间
在做这样的正则表达式时。
我相信您可以将此代码翻译成 vb。
它基本上只是分解每个短语的第一个字母并创建一个
连接在一起的那些短语的数组。我使用哈希来做到这一点,
但可以通过对所有短语进行排序,然后循环遍历来轻松完成
每个都代表相等的第一个字母。
首先,拥有 +1000 个短语可能会包含大部分字母
作为短语中某处的起始字符,因此普通的 trie 不会有太大帮助
在平面正则表达式中。
然后,在平面正则表达式的情况下,必须测试每个短语,直到匹配。
这是源字符串中每个字符 +1000 次测试。相当多的开销。
当您将每个短语的第一个字母分解出来时,您可以立即将其除以 26。
当您这样做时,将为每个字母打开一个辅助 trie 类,进一步减少
开销很大的因素。
如果您为 2 个字符执行此操作,则开销几乎可以忽略不计。
下面仅显示了 FLAT 1 级 (trie) 正则表达式的调试,
和单个字符级别因子之一。
要分析正则表达式,请按照每个TRIEC-EXACTF[..] 中的路径表示一个终止
点(通过或失败)。
您可以看到 路径 显着减少。
Perl 代码:
use strict;
use warnings;
use Data::Dumper;
use re 'debug';
my @Flat_Rx_ary = ();
my @rx_ary = ();
my %LetterHash = ();
while (my $line = <DATA>)
{
chomp( $line );
next if ( length($line) == 0);
push ( @Flat_Rx_ary, $line );
my $first_char = substr( $line, 0, 1);
my $remainder = substr( $line, 1 );
if ( !defined( $LetterHash{ $first_char } )) {
$LetterHash{ $first_char } = [];
}
push ( @{$LetterHash{ $first_char }}, $remainder );
}
print Dumper(\%LetterHash);
# Factored regex ..
my @rx_parts = ();
foreach my $rx_key ( keys %LetterHash )
{
@{$LetterHash{ $rx_key }} = sort @{$LetterHash{ $rx_key }};
my $rx_val = join ( '|', @{$LetterHash{ $rx_key }} );
push ( @rx_parts, '(?:' . $rx_key . '(?:' . $rx_val . '))' );
}
my $total_rx = '(?i)\b(' . join( '|', @rx_parts ) . ')\b';
print $total_rx, "\n\n\n";
my $CompiledRx = qr /$total_rx/;
# Flat regex ..
@Flat_Rx_ary = sort ( @Flat_Rx_ary );
my $Flat_Total_Rx = '(?i)\b(' . join( '|',@Flat_Rx_ary) . ')\b';
print "\n\n\n", $Flat_Total_Rx, "\n\n\n";
my $CompiledFlatRx = qr /$Flat_Total_Rx/;
__DATA__
hello world
this is cool
good day
one day beyond
a very fine time
the end of the season
the trial of the centurn
total eclipse
game on
hello LA
输出:
$VAR1 = {
'a' => [
' very fine time'
],
'h' => [
'ello world',
'ello LA'
],
'g' => [
'ood day',
'ame on'
],
'o' => [
'ne day beyond'
],
't' => [
'his is cool',
'he end of the season',
'he trial of the centurn',
'otal eclipse'
]
};
(?i)\b((?:a(?: very fine time))|(?:h(?:ello LA|ello world))|(?:g(?:ame on|ood da
y))|(?:o(?:ne day beyond))|(?:t(?:he end of the season|he trial of the centurn|h
is is cool|otal eclipse)))\b
Compiling REx "(?i)\b((?:a(?: very fine time))|(?:h(?:ello LA|ello world))|"...
Final program:
1: BOUND (2)
2: OPEN1 (4)
4: TRIEC-EXACTF[AGHOTaghot] (74)
<a very fine time> (74)
<h> (15)
15: EXACTF <ello > (18)
18: TRIE-EXACTF[LWlw] (74)
<LA>
<world>
<g> (28)
28: TRIE-EXACTF[AOao] (74)
<ame on>
<ood day>
<one day beyond> (74)
<t> (48)
48: TRIEC-EXACTF[HOho] (74)
<he end of the season>
<he trial of the centurn>
<his is cool>
<otal eclipse>
74: CLOSE1 (76)
76: BOUND (77)
77: END (0)
stclass BOUND minlen 7
(?i)\b(a very fine time|game on|good day|hello LA|hello world|one day beyond|the
end of the season|the trial of the centurn|this is cool|total eclipse)\b
Compiling REx "(?i)\b(a very fine time|game on|good day|hello LA|hello worl"...
Final program:
1: BOUND (2)
2: OPEN1 (4)
4: TRIEC-EXACTF[AGHOTaghot] (60)
<a very fine time>
<game on>
<good day>
<hello LA>
<hello world>
<one day beyond>
<the end of the season>
<the trial of the centurn>
<this is cool>
<total eclipse>
60: CLOSE1 (62)
62: BOUND (63)
63: END (0)
stclass BOUND minlen 7
Freeing REx: "(?i)\b((?:a(?: very fine time))|(?:h(?:ello LA|ello world))|"...
Freeing REx: "(?i)\b(a very fine time|game on|good day|hello LA|hello worl"...