向作为参数传递的 qr 模式添加“m”修饰符

Mil*_*ler 9 regex perl

我希望能够将“m”修饰符添加到传递给函数的正则表达式中。

以下测试脚本演示了我正在尝试做的事情

#!/usr/bin/env perl

use strict;
use warnings;
use v5.16.3;

use Test::More tests => 3;

my $no_m_modifier_re   = qr{^line1\n^line2};
my $with_m_modifier_re = qr{^line1\n^line2}m;

my $text = <<'EoM';
line1
line2
line3
EoM

unlike( $text, $no_m_modifier_re, 'Text will not match ^ that is equivalent to \A' );
like( $text, $with_m_modifier_re, 'Text will match ^ with m modifier' );

# This fails to add the m modifier to the subexpression
my $add_m_modifier_re = qr{(?m)$no_m_modifier_re};
#my $add_m_modifier_re = qr{(?m:$no_m_modifier_re)};    # Experimented other syntax, with same result
#my $add_m_modifier_re = qr{$no_m_modifier_re}m;
#my $add_m_modifier_re = qr{(?^m:$no_m_modifier_re)};    # suggested by mob, didn't work.

like( $text, $add_m_modifier_re, 'Want this to match, but it fails to add m modifier to subexpression' );
Run Code Online (Sandbox Code Playgroud)

结果是

$ prove -v m_modifier.pl
m_modifier.pl ..
1..3
ok 1 - Text will not match ^ that is equivalent to \A
ok 2 - Text will match ^ with m modifier
not ok 3 - Want this to match, but it fails to add m modifier to subexpression

#   Failed test 'Want this to match, but it fails to add m modifier to subexpression'
#   at m_modifier.pl line 25.
#                   'line1
# line2
# line3
# '
#     doesn't match '(?^:(?m)(?^:^line1\n^line2))'
# Looks like you failed 1 test of 3.
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/3 subtests

Test Summary Report
-------------------
m_modifier.t (Wstat: 256 Tests: 3 Failed: 1)
  Failed test:  3
  Non-zero exit status: 1
Files=1, Tests=3,  1 wallclock secs ( 0.04 usr  0.01 sys +  0.14 cusr  0.05 csys =  0.24 CPU)
Result: FAIL
Run Code Online (Sandbox Code Playgroud)

如您所见,我尝试了不同的语法来添加 m 修饰符,但它们似乎都不适用于原始模式。

有任何想法吗?

这是在 Perl 5.16.3 下。我还没有尝试过更现代的版本。

ike*_*ami 3

qr{(?^m:$no_m_modifier_re)}按照你的建议尝试了,但仍然失败。测试报告doesn't match '(?^u:(?^m:(?^u:^line1\n^line2)))'

您正在尝试修改已编译的模式。为此,您需要以下内容:

use re qw( is_regexp regexp_pattern );

my $re = qr/^line1\n^line2/;

my ($pat, $mods) =
   is_regexp($re)
      ? regexp_pattern($re)
      : ( $re, "" );

$mods .= 'm' if $mods !~ /m/;

$re = eval("qr/\$pat/$mods")
   or die($@);  # Should never happen.
Run Code Online (Sandbox Code Playgroud)

它还适用于未编译的模式,从而生成具有最少(?:)嵌套的编译模式。

The result for   "abc"       is   qr/abc/m    which stringifies as   (?^um:abc)
The result for   qr/abc/     is   qr/abc/m    which stringifies as   (?^um:abc)
The result for   qr/abc/m    is   qr/abc/m    which stringifies as   (?^um:abc)
The result for   qr/abc/s    is   qr/abc/sm   which stringifies as   (?^ums:abc)
The result for   qr/abc/sm   is   qr/abc/sm   which stringifies as   (?^ums:abc)
Run Code Online (Sandbox Code Playgroud)