将德国变音符号与regexp正确匹配两次

问题描述 投票:1回答:2

我有一个小脚本,如果字符串包含äöüß这样的德语变音符号,则可以通过regexp进行匹配。在第一个正则表达式匹配中,一切正常,但是如果我再次检查相同的字符串,它将不再正确匹配。该文件本身被编码为utf8,我也包括utf8模块。

这是脚本:

#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use utf8;
use Log4Perl::logger_helper qw( init_logger get_logger_and_trace );

my $strings = ["ä", "ae","ö", "oe", "ü", "ue", "ß", "ss"];

my $logger = init_logger(
    log_file_path => $0 . '.log'
);    # init_logger variables are all optional

foreach my $string (@$strings) {
    for(1..5) {
        if ( $string =~ /[\x{00C4}\x{00E4}\x{00D6}\x{00F6}\x{00DC}\x{00FC}\x{00DF}]/gi ) {
            $logger->info("umlauts match $string");
        }
        else {
            $logger->info("no umlauts $string");
        }
    }
 }

这是输出:

umlauts match ä
no umlauts ä
umlauts match ä
no umlauts ä
umlauts match ä
no umlauts ae
no umlauts ae
no umlauts ae
no umlauts ae
no umlauts ae
umlauts match ö
no umlauts ö
umlauts match ö
no umlauts ö
umlauts match ö
no umlauts oe
no umlauts oe
no umlauts oe
no umlauts oe
no umlauts oe
umlauts match ü
no umlauts ü
umlauts match ü
no umlauts ü
umlauts match ü
no umlauts ue
no umlauts ue
no umlauts ue
no umlauts ue
no umlauts ue
umlauts match ß
no umlauts ß
umlauts match ß
no umlauts ß
umlauts match ß
no umlauts ss
no umlauts ss
no umlauts ss
no umlauts ss
no umlauts ss

Process finished with exit code 0

我在具有不同版本的Strawberry Perl的不同操作系统上进行了测试,也为我显示了此错误的最新版本(strawberry-perl-5.30.0.1-64bit-portable)。

任何想法,为什么它匹配正确?如果我对多个索引操作执行相同操作,则它正在工作。

提前感谢。

regex perl pattern-matching diacritics strawberry-perl
2个回答
1
投票

问题是global标志。删除它。


0
投票

@daxim所述,全局标志/g在这里造成严重破坏。

Regexp Quote-Like Operators开始,重要部分以粗体]突出显示:

在标量上下文中,每次执行m//g都会找到下一个匹配项,如果匹配,则返回true;如果没有其他匹配,则返回false。可以使用pos()读取或设置最后一场比赛之后的位置功能。 失败的比赛

通常重置搜索位置到字符串的开头,但可以避免通过添加pos()修饰符(例如/c)。修改目标字符串也会重置搜索位置。

由于您在相同的m//gc中反复搜索(之间没有进行修改,因此,在上一次成功匹配后,第二个搜索将继续进行,导致失败并为下一个搜索重置搜索位置。

另请参见$string中的“全局匹配”:

修饰符Using regular expressions in Perl代表全局匹配,并允许匹配运算符,以便在一个字符串中尽可能多地匹配。标量中在上下文中,对字符串的连续调用将具有/g跳转从匹配到匹配,保持在字符串中的位置继续。您可以使用/g获取或设置位置功能。

[ciao,丹尼尔:-)

© www.soinside.com 2019 - 2024. All rights reserved.