将 "m" 修饰符添加到作为参数传递的 qr 模式
Add "m" modifier to qr pattern passed as parameter
我希望能够将“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' );
结果是
$ 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
如您所见,我尝试了不同的语法来添加 m 修饰符,但其中 none 似乎适用于原始模式。
有什么想法吗?
这是在 Perl 5.16.3 下。我还没有尝试过更现代的版本。
你快到了。在 Perl 5.16.3 中,它是
qr/(?^m:pattern)/ # equiv to /pattern/m
在较早的版本中,它类似于
qr/(?m-xis:pattern)/ # equiv to /pattern/m
qr/(?ix-ms:patterm)/ # equiv to /pattern/ix
这不适用于所有正则表达式修饰符。特别是,/g
修饰符不能以这种方式模拟。
演示:
$ perl -E 'say 0 + ("CAT" =~ /cat/)'
0
$ perl -E 'say 0 + ("CAT" =~ /(?^i:cat)/)'
1
更新:找到文档 here。摘录太长,但它们比我的回答提供了对“嵌入式模式匹配修饰符”更广泛和更深入的理解。
自 5.14(含)以来,您的方法已被破坏。
替换:
# This fails to add the m modifier to the subexpression
my $add_m_modifier_re = qr{(?m)$no_m_modifier_re};
(?^u:(?m)(?^u:^line1\n^line2))
有:
my $add_m_modifier = $no_m_modifier_re;
$add_m_modifier =~ s/:/m:/;
my $add_m_modifier_re = qr{$add_m_modifier};
(?^u:(?^um:^line1\n^line2))
我从来没有用过 Perl,所以不要怪我! ;D
https://perldoc.perl.org/perl5140delta#(?%5E...)-construct-signifies-default-modifiers
问题是您需要更改一个 qr
编辑的表达式,它是一个 regex object which
...magically differs from a string containing the same characters: ref(qr/x/)
returns "Regexp"; however, dereferencing it is not well defined...
我找不到更改它或向其添加标志的方法(除了编辑其字符串化)。
但是,如果您可以更改方法以定义(非qr
)变量开始,然后根据需要定义qr
-它们,那么它会按预期工作
use strict;
use warnings;
use v5.16.3;
use Test::More tests => 3;
my $no_m_modifier_re = q{^line1\n^line2}; # not qr{} but q{}; just a string
my $text = <<'EoM';
line1
line2
line3
EoM
unlike( $text, qr{$no_m_modifier_re}, 'Text does not match ^ equivalent to \A' );
like( $text, qr{$no_m_modifier_re}m, 'Text matches with the modifier' );
like( $text, qr{(?m)$no_m_modifier_re}, 'Text matches with the modifier' );
除了字符串,还可以设置 qr
-ed 变量,为方便起见,† 但主要思想是用户形成正则表达式模式进行必要的微调,例如通过修饰符。
† 如果其中任何一个可能被传来传去,它们可以通过 ref
来区分
I tried qr{(?^m:$no_m_modifier_re)}
like you suggested, but it still fails. The test reports 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.
它也适用于未编译的模式,从而产生具有最小 (?:)
嵌套的编译模式。
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)
我希望能够将“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' );
结果是
$ 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
如您所见,我尝试了不同的语法来添加 m 修饰符,但其中 none 似乎适用于原始模式。
有什么想法吗?
这是在 Perl 5.16.3 下。我还没有尝试过更现代的版本。
你快到了。在 Perl 5.16.3 中,它是
qr/(?^m:pattern)/ # equiv to /pattern/m
在较早的版本中,它类似于
qr/(?m-xis:pattern)/ # equiv to /pattern/m
qr/(?ix-ms:patterm)/ # equiv to /pattern/ix
这不适用于所有正则表达式修饰符。特别是,/g
修饰符不能以这种方式模拟。
演示:
$ perl -E 'say 0 + ("CAT" =~ /cat/)'
0
$ perl -E 'say 0 + ("CAT" =~ /(?^i:cat)/)'
1
更新:找到文档 here。摘录太长,但它们比我的回答提供了对“嵌入式模式匹配修饰符”更广泛和更深入的理解。
自 5.14(含)以来,您的方法已被破坏。
替换:
# This fails to add the m modifier to the subexpression
my $add_m_modifier_re = qr{(?m)$no_m_modifier_re};
(?^u:(?m)(?^u:^line1\n^line2))
有:
my $add_m_modifier = $no_m_modifier_re;
$add_m_modifier =~ s/:/m:/;
my $add_m_modifier_re = qr{$add_m_modifier};
(?^u:(?^um:^line1\n^line2))
我从来没有用过 Perl,所以不要怪我! ;D
https://perldoc.perl.org/perl5140delta#(?%5E...)-construct-signifies-default-modifiers
问题是您需要更改一个 qr
编辑的表达式,它是一个 regex object which
...magically differs from a string containing the same characters:
ref(qr/x/)
returns "Regexp"; however, dereferencing it is not well defined...
我找不到更改它或向其添加标志的方法(除了编辑其字符串化)。
但是,如果您可以更改方法以定义(非qr
)变量开始,然后根据需要定义qr
-它们,那么它会按预期工作
use strict;
use warnings;
use v5.16.3;
use Test::More tests => 3;
my $no_m_modifier_re = q{^line1\n^line2}; # not qr{} but q{}; just a string
my $text = <<'EoM';
line1
line2
line3
EoM
unlike( $text, qr{$no_m_modifier_re}, 'Text does not match ^ equivalent to \A' );
like( $text, qr{$no_m_modifier_re}m, 'Text matches with the modifier' );
like( $text, qr{(?m)$no_m_modifier_re}, 'Text matches with the modifier' );
除了字符串,还可以设置 qr
-ed 变量,为方便起见,† 但主要思想是用户形成正则表达式模式进行必要的微调,例如通过修饰符。
† 如果其中任何一个可能被传来传去,它们可以通过 ref
I tried
qr{(?^m:$no_m_modifier_re)}
like you suggested, but it still fails. The test reportsdoesn'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.
它也适用于未编译的模式,从而产生具有最小 (?:)
嵌套的编译模式。
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)