Warm tip: This article is reproduced from serverfault.com, please click

其他-在外国字符集的perl中进行字符串比较的更快方法

(其他 - Faster way to do this comparison of string in perl for foreign charsets)

发布于 2020-11-28 08:36:56

我有下面的代码,效果很好:

foreach my $type (qw/Arabic Armenian Bengali Bopomofo Braille Buhid Canadian_Aboriginal Cherokee Cyrillic Devanagari Ethiopic Georgian Greek Gujarati Gurmukhi Han Hangul Hanunoo Hebrew Hiragana Kannada Katakana Khmer Lao Limbu Malayalam Mongolian Myanmar Ogham Oriya Runic Sinhala Syriac Tagalog Tagbanwa TaiLe Tamil Telugu Thaana Thai Tibetan/) {
    if ($page_title =~ /\p{Script_Extensions=$type}/i) {

        print qq|TITLE: $_->{domain} is not english ($type), so lets ignore it...\n| if $DEBUG > 0;

        last;
    }
}

它所做的只是寻找某些字符集,因此我们可以摆脱那些我们不想要的字符集。现在,尽管它可以正常工作,但它有点慢(因为它对foreach()每个对象都执行一个操作)。有没有办法在单个正则表达式中做到这一点?(并在可能的情况下提取匹配集)

更新:我现在正在尝试与建议:

if ($page_title =~ /\p{Script_Extensions=Han|Arabic|Armenian|Bengali|Bopomofo|Braille|Buhid|Canadian_Aboriginal|Cherokee|Cyrillic|Devanagari|Ethiopic|Georgian|Greek|Gujarati|Gurmukhi|Hangul|Hanunoo|Hebrew|Hiragana|Kannada|Katakana|Khmer|Lao|Limbu|Malayalam|Mongolian|Myanmar|Ogham|Oriya|Runic|Sinhala|Syriac|Tagalog|Tagbanwa|TaiLe|Tamil|Telugu|Thaana|Thai|Tibetan}/i) {
    colored(qq|$page_title matches $1, so lets ignore... |, 'yellow on_magenta'), "\n";
}

并且:

if ($page_title =~ /\p{Script_Extensions=(Han|Arabic|Armenian|Bengali|Bopomofo|Braille|Buhid|Canadian_Aboriginal|Cherokee|Cyrillic|Devanagari|Ethiopic|Georgian|Greek|Gujarati|Gurmukhi|Hangul|Hanunoo|Hebrew|Hiragana|Kannada|Katakana|Khmer|Lao|Limbu|Malayalam|Mongolian|Myanmar|Ogham|Oriya|Runic|Sinhala|Syriac|Tagalog|Tagbanwa|TaiLe|Tamil|Telugu|Thaana|Thai|Tibetan)}/i) {
    colored(qq|$page_title matches $1, so lets ignore... |, 'yellow on_magenta'), "\n";
}

但是我得到一个错误:

找不到Unicode属性定义“ Script_Extensions = Han |阿拉伯语|亚美尼亚语|孟加拉语| Bopomofo | Braille | Buhid | Canadian_Aboriginal | Cherokee | Cyrillic | Devanagari | Ethiopic | Georgian | Greek | Gujarati | GurmukhiHi | Hangul | Hanunoo Kannada | Katakana |高棉|老挝|林布|马拉雅拉姆语|蒙古语|缅甸|奥格姆|奥里亚语|符文|僧伽罗语|叙利亚|塔加洛格|塔班瓦|泰勒|泰米尔语|泰卢固语|塔哈纳|泰国|藏语“在正则表达式中;在进程所有域.cgi行300中,在m / \ p {Script_Extensions = Han |阿拉伯语|亚美尼亚语|孟加拉语| Bopomofo | Braille | Buhid | Canadian_Aboriginal | Che中用<-HERE标记。

Questioner
Andrew Newby
Viewed
0
ikegami 2020-11-29 15:22:32

首先,我猜想使用没有任何意义/i

对于解决方案,交替是一种选择。

/
     \p{Script_Extensions=Arabic}
   | \p{Script_Extensions=Armenian}
   | \p{Script_Extensions=Bengali}
   | ...
   | \p{Script_Extensions=Thaana}
   | \p{Script_Extensions=Thai}
   | \p{Script_Extensions=Tibetan}
/x

交替允许我们使用空格,但是更快的解决方案是字符类。

/
   [\p{Script_Extensions=Arabic}\p{Script_Extensions=Armenian}\p{Script_Extensions=Bengali}...\p{Script_Extensions=Thaana}\p{Script_Extensions=Thai}\p{Script_Extensions=Tibetan}]
/x

但是,在41个属性中,只有3个占据了屏幕的整个宽度。与此处介绍的其他解决方案一样,没有什么可以阻止你动态构建模式。

my $class_body =
   join '',
      map "\\p{Script_Extensions=$_}",
         qw(
            Arabic Armenian Bengali
            ...
            Thaana Thai Tibetan
         );

/[$class_body]/

但是还有另一种选择: (?[...])

use experimental qw( regex_sets );

/
   (?[ \p{Script_Extensions=Arabic}
   +   \p{Script_Extensions=Armenian}
   +   \p{Script_Extensions=Bengali}
   +   ...
   +   \p{Script_Extensions=Thaana}
   +   \p{Script_Extensions=Thai}
   +   \p{Script_Extensions=Tibetan}
   ])
/x

它仍处于实验阶段,但我认为它很稳定,很可能将其转化为语言。