代码之家  ›  专栏  ›  技术社区  ›  Wes

(?)的含义?^:)在perl编译的regex中[duplicate]

  •  0
  • Wes  · 技术社区  · 7 年前

    我正试图修复一个很旧的脚本,它试图找到一个字符串 FILE_DESC_LIMIT 在文本文件中更改为其他内容。

    对于这个我当前的脚本,它在Perl5.10上运行良好,我看到它使用了一个正则表达式

        qr!^FILE_DESC_LIMIT=\d+(\s*)!;
    

    但这在Perl5.16中不起作用,所以我试图打印这个表达式。 在5.10我明白了

        (?-xism:\bFILE_DESC_LIMIT=\d+(\s*))
    

    在Perl5.16中,我看到

        (?^:^FILE_DESC_LIMIT=\d+(\s*))
    

    我懂了 qr 正在添加 -xism 虽然它没有在5.16中添加它,为什么这里有区别?

    如果我在正则表达式中显式地添加它,它就会工作。但是我怀疑这个解决方案,因为Perl没有显式地添加它,所以这里可能有一些问题。

    对于Perl5.16,我应该使用一些不同的方法吗? Perl为什么改变了这种行为?

    我的代码是这样的,我们创建一个正则表达式,然后使用正则表达式,我们模拟一个表达式,然后在一个打开的文件上求值,然后将求值输出写入同一个文件。

    my atempRegex=qr!^FILE_DESC_LIMIT=\d+(\s*)!;
    my $replaceSting => qq!FILE_DESC_LIMIT=$FileDescLimit\$1!
    
    $tempRegex =~ s!\^!\\b!g if ($] =~ /5\.010/);
    
    my $code .= "\$File =~ s!$tempRegex!$replaceSting!gsm;\n";
    
    open (FH, "<$WORKING_DIR/$base_script_name.$$.tmp") || logWrite2(E,"-- 
    ERROR: Unable to open $WORKING_DIR/$base_script_name.$$.tmp for reading 
    ($!)");
    
    my $File = join("",<FH>);
    close (FH);
    
    eval $code;
    
    open (FH, ">$WORKING_DIR/$base_script_name.$$.tmp") || logWrite2(E,"-- 
    ERROR: Unable to open $WORKING_DIR/$base_script_name.$$.tmp for writing 
    ($!)");
    
    print FH $File;
    close (FH);
    

    我在Perl 5.16中执行的更改是,我将-XISM修饰符显式添加到正则表达式中,也修改了\b修饰符条件。

    my $FileDescLimit=2048;
    my $tempRegex=qr!^FILE_DESC_LIMIT=\d+(\s*)!;
    my $replaceSting => qq!FILE_DESC_LIMIT=$FileDescLimit\$1!
    
    if ($] >=5.016)
    {
        $tempRegex=~ s!\^!-xism!;
    }
    $tempRegex =~ s!\^!\\b!g if ($] >=5.010);
    
    my $code .= "\$File =~ s!$tempRegex!$replaceSting!gsm;\n";
    
    open (FH, "<$WORKING_DIR/$base_script_name.$$.tmp") || logWrite2(E,"-- ERROR: Unable to open $WORKING_DIR/$base_script_name.$$.tmp for reading ($!)");
    
    my $File = join("",<FH>);
    close (FH);
    
    eval $code;
    
    open (FH, ">$WORKING_DIR/$base_script_name.$$.tmp") || logWrite2(E,"-- ERROR: Unable to open $WORKING_DIR/$base_script_name.$$.tmp for writing ($!)")
    print FH $File;
    close (FH);
    

    我不知道这个问题是因为-XISM修饰符还是因为\B修饰符,因为我看到脚本在版本5.10上被修改了,并且B修饰符被显式地添加了,真正的问题是用这个修饰符。

    指的是下面的一个答案?^相当于?XISM,我删除了代码

    if ($] >=5.016)
    {
        $tempRegex=~ s!\^!-xism!;
    }
    

    从我的脚本中,X-ISM不再是我的正则表达式的一部分,我在我的正则表达式中添加了B,就像Perl版本5.10所做的那样,下面的代码替换了正则表达式中的第二个插入符号,(?)^“^FILE_DESC_LIMIT=\d+(\s*))与\b一起使用,结果是regex(?)?^:\bFILE_DESC_LIMIT=\d+(\s*),字符串匹配并替换

    if ($] =~ /5\.016/)
    {
        my $n=0;
        $Source =~ s/\^/++$n==2?"\\b":"\^"/ge
    }
    

    正如我在regex教程中看到的,b用于定义单词边界和执行整个单词匹配,我不清楚为什么它不能匹配 FILE_DESC_LIMIT=2048不带b的文件中的字符串。

    0 回复  |  直到 9 年前
        1
  •  2
  •   Borodin    9 年前

    这个 documentation on Extended Patterns in perlre 有这个

    从Perl5.14开始,a "^" (插入符号或扬抑符重音)紧跟在 "?" 是相当于 d-imnsx . 旗帜(除了 "d" )可以跟随插入符号覆盖它。但是负号是不合法的。

    在那些修饰语中, -imsx 与您在v5.10中看到的内容相匹配,而 -n 启用括号和 d 启用“默认”字符集行为。最后两个是新的修饰符

    这些都与您在v5.10中显示的值没有任何不同,因此您将必须显示您的数据和您编写的内容,以获得行为上的更改

        2
  •  1
  •   choroba    9 年前

    Regular Expressions in Perl 5.14 Delta :的 (?^ 现在表示默认修饰符。只是编译的正则表达式如何序列化的问题,更重要的是 \b ^ 在你的正则表达式中。