插入符号(?^:...)在Perl qr //正则表达式的字符串形式中是什么意思?

时间:2017-05-10 21:17:18

标签: regex perl

考虑这个基于答案的脚本 关于解析罗马的SO 267399 数字,虽然解析罗马数字是偶然的 问题

#!/usr/bin/env perl
#
# Based on answer to SO 0026-7399

use warnings;
use strict;

my $qr1 = qr/(?i:M{1,3})/;
my $qr2 = qr/(?i:C[MD]|D?C{1,3})/;
my $qr3 = qr/(?i:X[CL]|L?X{1,3})/;
my $qr4 = qr/(?i:I[XV]|V?I{1,3})/;

print "1000s: $qr1\n";
print " 100s: $qr2\n";
print "  10s: $qr3\n";
print "   1s: $qr4\n";

# This $qr is too simple — it matches the empty string
#my $qr = qr/($qr1?$qr2?$qr3?$qr4?)/;

my $qr = qr/\b((?:$qr1$qr2?$qr3?$qr4?)|(?:$qr2$qr3?$qr4?)|(?:$qr3$qr4?)|(?:$qr4))\b/;

print " Full: $qr\n";

while (<>)
{
    chomp;
    print " Line: [$_]\n";
    while ($_ =~ m/$qr/g)
    {
        print "Match: [$1] found in [$_] using qr//\n";
    }
}

鉴于下面的数据文件,前三行各包含一个罗马数字。

mix in here
no mix in here
mmmcmlxxxix
minimum

在现在运行macOS Sierra的Mac上运行(自制)Perl 5.22.0时 10.12.4,我得到这样的输出(但Perl的版本不是 临界):

1000s: (?^:(?i:M{1,3}))
 100s: (?^:(?i:C[MD]|D?C{1,3}))
  10s: (?^:(?i:X[CL]|L?X{1,3}))
   1s: (?^:(?i:I[XV]|V?I{1,3}))
 Full: (?^:\b((?:(?^:(?i:M{1,3}))(?^:(?i:C[MD]|D?C{1,3}))?(?^:(?i:X[CL]|L?X{1,3}))?(?^:(?i:I[XV]|V?I{1,3}))?)|(?:(?^:(?i:C[MD]|D?C{1,3}))(?^:(?i:X[CL]|L?X{1,3}))?(?^:(?i:I[XV]|V?I{1,3}))?)|(?:(?^:(?i:X[CL]|L?X{1,3}))(?^:(?i:I[XV]|V?I{1,3}))?)|(?:(?^:(?i:I[XV]|V?I{1,3}))))\b)
 Line: [mix in here]
Match: [mix] found in [mix in here] using qr//
 Line: [no mix in here]
Match: [mix] found in [no mix in here] using qr//
 Line: [mmmcmlxxxix]
Match: [mmmcmlxxxix] found in [mmmcmlxxxix] using qr//
 Line: [minimum]

我不理解输出的唯一部分是插入符号^ (?^:…)符号。

我查看了Perl文档 perlreperlref甚至是 perlop 关于'正则表达式引用的运算符'没有看到这个例证或 解释。 (当您提出有关正则表达式的问题时,我还检查了SO建议的资源。(?^:字符串经过精心设计,可以为搜索引擎提供一些条件。)

我的问题分为两部分:

  1. (?^:…)中插入符号的重要性及其原因 它被添加到qr//正则表达式?
  2. 如果重要,你如何阻止它被添加到qr//正则表达式?

2 个答案:

答案 0 :(得分:8)

基本上它意味着默认标志适用(即使它被内插到指定不同的正则表达式)。 在它被引入之前,qr会产生类似(?-ismx:的东西,并且添加到Perl的新标志会进行更改,这样可以保持测试 迄今为止的痛苦。

http://perldoc.perl.org/perlre.html#Extended-Patterns

从Perl 5.14开始,&#34; ^&#34; (&#34;?&#34;是d-imnsx的简写。标志(&#34; d&#34;除外)可以跟随插入符号覆盖它。但减号不合法。

答案 1 :(得分:5)

这意味着“将所有标记(例如is)设置为默认值”,所以

$ perl -le'my $re = "a"; for (qw( a A )) { print "$_: ", /$re/i ? "match" : "no match"; }'
a: match
A: match

$ perl -le'my $re = "(?^:a)"; for (qw( a A )) { print "$_: ", /$re/i ? "match" : "no match"; }'
a: match
A: no match

它主要用于表示由qr //.

创建的模式
$ perl -le'my $re = qr/a/; print $re; for (qw( a A )) { print "$_: ", /$re/i ? "match" : "no match"; }'
(?^:a)
a: match
A: no match

$ perl -le'my $re = qr/a/i; print $re; for (qw( a A )) { print "$_: ", /$re/i ? "match" : "no match"; }'
(?^i:a)
a: match
A: match