re - Perl pragma 用于更改正则表达式行为
use re 'taint';
($x) = ($^X =~ /^(.*)$/s); # $x is tainted here
$pat = '(?{ $foo = 1 })';
use re 'eval';
/foo${pat}bar/; # won't fail (when not under -T
# switch)
{
no re 'taint'; # the default
($x) = ($^X =~ /^(.*)$/s); # $x is not tainted here
no re 'eval'; # the default
/foo${pat}bar/; # disallowed (with or without -T
# switch)
}
use re 'strict'; # Raise warnings for more conditions
use re '/ix';
"FOO" =~ / foo /; # /ix implied
no re '/x';
"FOO" =~ /foo/; # just /i implied
use re 'debug'; # output debugging info during
/^(.*)$/s; # compile and run time
use re 'debugcolor'; # same as 'debug', but with colored
# output
...
use re qw(Debug All); # Same as "use re 'debug'", but you
# can use "Debug" with things other
# than 'All'
use re qw(Debug More); # 'All' plus output more details
no re qw(Debug ALL); # Turn on (almost) all re debugging
# in this scope
use re qw(is_regexp regexp_pattern); # import utility functions
my ($pat,$mods)=regexp_pattern(qr/foo/i);
if (is_regexp($obj)) {
print "Got regexp: ",
scalar regexp_pattern($obj); # just as perl would stringify
} # it but no hassle with blessed
# re's.
(我们在这些示例中使用 $^X,因为它默认是受污染的。)
当 use re 'taint'
生效,并且受污染的字符串是正则表达式的目标时,正则表达式内存(或 m// 运算符在列表上下文中返回的值)将受到污染。当对受污染数据的正则表达式操作并非用于提取安全的子字符串,而是执行其他转换时,此功能非常有用。
当 use re 'eval'
生效时,正则表达式允许包含 (?{ ... })
零宽度断言和 (??{ ... })
延迟子表达式,这些断言和子表达式源自变量插值,而不是直接出现在正则表达式中。这通常是不允许的,因为它是一个潜在的安全风险。请注意,当正则表达式从受污染的数据中获取时,此 pragma 将被忽略,即受污染的正则表达式始终不允许求值。请参阅 "(?{ code })" in perlre 和 "(??{ code })" in perlre。
对于此 pragma,预编译正则表达式的插值(即 qr//
的结果)不被视为变量插值。因此
/foo${pat}bar/
如果 $pat 是预编译的正则表达式,则允许,即使 $pat 包含 (?{ ... })
断言或 (??{ ... })
子表达式。
请注意,这是一项实验性功能,可能会在未来的 Perl 版本中更改或删除。
当 use re 'strict'
生效时,在编译正则表达式模式时,将应用比平时更严格的检查。这些检查可能会导致发出比平时更多的警告,并且更多内容会变成致命错误,而不仅仅是警告。这样做的目的是在编译时查找并报告某些内容,这些内容可能是合法的,但很有可能不是程序员的实际意图。这会在其范围内自动启用 "regexp"
警告类别(如果尚未启用)。
作为在 "strict'
下被捕获但其他情况下不会被捕获的示例,模式是
qr/\xABC/
"\x"
结构在没有大括号的情况下应该紧跟两个十六进制数字;这个结构紧跟三个十六进制数字。这当前被评估为等同于
qr/\x{AB}C/
即,代码点值为 0xAB
的字符,后跟字母 C
。但是由于 C
是一个十六进制数字,因此有合理的可能意图是
qr/\x{ABC}/
即 0xABC
处的单个字符。在 'strict'
下,不使用两个十六进制数字紧跟 \x
是一个错误。当不在 'strict'
下时,如果只有一个十六进制数字,则会生成警告,如果有多于两个十六进制数字,则不会发出警告。
随着我们获得经验,'strict'
确切执行的操作预计会随着时间的推移而演变。这意味着在当今 Perl 中在其下编译的程序在未来的 Perl 中可能无法编译,或者可能会有更多或更少的警告。对此没有向后兼容性承诺。此外,已经提出了启用它的备用语法的建议。由于这些原因,使用它将引发 experimental::re_strict
类警告,除非该类别已关闭。
请注意,如果在 'strict'
中编译的模式被重新编译,比如通过插值到另一个模式中,在 'strict'
之外,则不会再次检查其严格性。这是因为如果它在严格下有效,那么它必须在非严格下有效。
当指定 use re '/flags'
时,给定的 flags 会自动添加到每个正则表达式中,直到词法范围结束。flags 可以是 'a'
、'aa'
、'd'
、'i'
、'l'
、'm'
、'n'
、'p'
、's'
、'u'
、'x'
和/或 'xx'
的任意组合。
no re '/flags'
将关闭 use re '/flags'
对给定标志的影响。
例如,如果您希望所有正则表达式默认启用 /msxx,只需在代码顶部放置
use re '/msxx';
即可。
字符集 /adul
标志相互抵消。因此,在此示例中,
use re "/u";
"ss" =~ /\xdf/;
use re "/d";
"ss" =~ /\xdf/;
第二个 use re
执行隐式 no re '/u'
。
类似地,
use re "/xx"; # Doubled-x
...
use re "/x"; # Single x from here on
...
使用 use re
启用其中一个字符集标志优先于 locale
pragma 和正则表达式的 'unicode_strings' feature
。在活动状态下关闭其中一个标志将恢复由作用域中的任何其他语用程序指定的行为。例如
use feature "unicode_strings";
no re "/u"; # does nothing
use re "/l";
no re "/l"; # reverts to unicode_strings behaviour
当 use re 'debug'
生效时,perl 在编译和使用正则表达式时会发出调试消息。输出与使用 -Dr 开关运行启用了 -DDEBUGGING
的 perl 解释器获得的输出相同。它可能会非常庞大,具体取决于匹配的复杂性。使用 debugcolor
代替 debug
可以启用一种输出形式,该形式可用于在理解 termcap 颜色序列的终端上获得彩色显示。将 $ENV{PERL_RE_TC}
设置为逗号分隔的 termcap
属性列表,用于打开/关闭字符串的高亮显示、打开/关闭前点部分。有关其他信息,请参阅 "perldebug 中的“调试正则表达式”。
请注意,debug
模式的确切格式不被视为 Perl 的官方支持 API。它仅用于调试,并且可能会在 Perl 的任何主要或次要版本中更改,而无需事先通知或弃用,具体取决于核心开发团队认为合适。输出的任何文档纯粹是建议性的。
从 5.9.5 开始,指令 use re 'debug'
及其等效项具有词法作用域,就像其他指令一样。但是,它们同时具有编译时和运行时效果。
请参阅 "perlmodlib 中的“实用模块”。
类似地,use re 'Debug'
会生成调试输出,不同之处在于它允许微调将发出的调试输出。选项分为三组:与编译相关的选项、与执行相关的选项以及与特殊用途相关的选项。
注意,Debug
模式下提供的选项及其创建的输出的具体格式不是 Perl 官方支持的 API。它仅用于调试,并且可能会在 Perl 的任何版本(主要版本或次要版本)中根据核心开发团队认为合适的情况而更改,恕不另行通知或弃用。格式或可用选项的任何文档仅供参考,并且可能会在不另行通知的情况下更改。
选项如下
启用所有“额外”调试选项。
启用在匹配期间调试捕获组存储。警告,这可能会产生非常大的输出。
启用增强的 TRIE 调试。增强了 TRIEE 和 TRIEC。
启用引擎中状态的调试。
启用引擎中递归堆栈的调试。启用或禁用此选项会自动对调试状态执行相同的操作。此输出可能很大。
启用 \G 修饰符的调试。
启用增强的优化调试和起点优化。可能只有在调试正则表达式引擎本身时才有用。
启用在优化阶段之前转储已编译模式。
当 Perl 遇到通配符子模式(请参阅 perlunicode 中的“属性值中的通配符”)时,它会暂停主模式的编译,编译子模式,然后根据所有合法可能性对其进行匹配以确定子模式匹配的实际代码点。然后,它将这些代码点添加到主模式中,并继续其编译。
您可能非常想了解您的子模式是如何编译的,但了解 Perl 如何根据所有合法可能性对其进行匹配对您来说可能用处不大,因为这是由 Perl 控制的,而不是您。因此,编译部分的调试信息由其他选项指定,但匹配部分的调试输出通常被抑制。
您可以使用 WILDCARD 选项启用此子模式匹配的调试输出。小心!这可能会导致大量输出,并且 Perl 为什么会执行其执行的操作可能对您来说没有多大意义。但它可能有助于您了解事情为何没有按照您的预期进行。
请注意,此选项本身不会导致输出任何调试信息。它的作用是停止在通配符编译的匹配部分期间对执行相关的调试信息进行正常的抑制。您还必须指定您想要的执行调试信息,例如通过同时包含 EXECUTE 选项。
这些是有用的快捷方式,可节省输入。
从 5.9.5 开始,指令 use re 'debug'
及其等效指令具有词法作用域,其他指令也是如此。但是,它们同时具有编译时和运行时效果。
从 perl 5.9.5 开始,“re”调试包含许多实用函数,这些函数可以根据需要导出到调用者的命名空间。它们如下所示。
如果参数是 qr//
返回的已编译正则表达式,则返回 true;如果不是,则返回 false。
此函数不会因重载或祝福而混淆。在内部术语中,这会从 PERL_MAGIC_qr 结构中提取正则表达式指针,因此不会被愚弄。
如果参数是 qr//
返回的已编译正则表达式,则此函数返回模式。
在列表上下文中,它返回一个包含两个元素的列表,第一个元素包含模式,第二个元素包含编译模式时使用的修饰符。
my ($pat, $mods) = regexp_pattern($ref);
在标量上下文中,它返回的内容与 perl 在对包含相同模式的原始 qr//
进行字符串化时返回的内容相同。如果参数不是已编译的引用,则此例程在标量上下文中返回 false 但已定义,在列表上下文中返回空列表。因此,以下内容
if (regexp_pattern($ref) eq '(?^i:foo)')
无论 $ref 实际是什么,都将不发出警告。
与 is_regexp
一样,此函数不会因对象的重载或祝福而混淆。
返回上次成功匹配的命名缓冲区的内容。如果 $all 为 true,则返回一个数组引用,其中每个缓冲区包含一个条目,否则返回第一个已定义的缓冲区。
返回上次成功匹配中定义的所有命名缓冲区的列表。如果 $all 为真,则返回定义的所有名称,否则只返回参与匹配的名称。
返回用于上次成功匹配的模式中定义的不同名称的数量。
注意:此结果始终是定义的不同命名缓冲区的实际数量,它可能与 regnames()
和相关例程未使用 $all 参数调用时返回的结果不匹配。
如果参数是 qr//
返回的已编译正则表达式,则此函数返回优化器认为模式中最长的锚定固定字符串和最长的浮动固定字符串。
固定字符串 被定义为模式匹配必须出现的子字符串。锚定固定字符串 是必须出现在匹配开始处特定偏移量的固定字符串。浮动固定字符串 被定义为可以出现在匹配开始处相对位置范围内的任何点的固定字符串。例如,
my $qr = qr/here .* there/x;
my ($anchored, $floating) = regmust($qr);
print "anchored:'$anchored'\nfloating:'$floating'\n";
导致
anchored:'here'
floating:'there'
因为 here
在模式中位于 .*
之前,所以可以精确地确定其位置。然而,there
并非如此;它可以出现在锚定字符串出现后的任何位置。Perl 将两者都用于其优化,优先选择较长的,或者如果它们相等,则优先选择浮动的。
注意:这未必是明确的最长的锚定和浮动字符串。这将是您正在使用的 Perl 的优化器认为的最长的字符串。如果您认为结果错误,请通过 perlbug 实用程序报告。
如果参数是 qr//
返回的已编译正则表达式,则此函数返回在编译时发现的优化信息的哈希引用,以便我们可以围绕它编写测试。如果给出了任何其他参数,则返回 undef
。
随着我们开发新的优化方法,哈希内容有望不时发生变化 - 不应做出任何稳定性的假设,甚至在 perl 的次要版本之间也不应如此。
对于当前版本,哈希将具有以下内容
一个整数,任何可以匹配的字符串中最少的字符数。
一个整数,匹配后 $&
中可以包含的最少字符数。(例如考虑 /ns(?=\d)/
。)
一个整数,在 pos()
之前开始匹配的字符数。
一个布尔值,TRUE
表示不应使用找到的任何锚定/浮动子字符串。(CHECKME:显然这是为没有浮动子字符串的锚定模式设置的,但从未使用过。)
一个布尔值,TRUE
表示优化器信息是正则表达式包含的所有内容,因此根本不需要进入正则表达式运行时引擎。
一个布尔值,如果模式锚定到字符串的开头,则为 TRUE
。
一个布尔值,如果模式锚定到字符串内的任何行开头,则为 TRUE
。
一个布尔值,如果模式锚定到前一个匹配的结尾,则为 TRUE
。
一个布尔值,如果开始类只能匹配一个运行中的第一个,则为 TRUE
。
一个布尔值,如果 /.*/
已隐式转换为 /^.*/
,则为 TRUE
。
一个字节字符串,分别表示任何匹配必须包含的锚定或浮动子字符串,或如果未找到此类子字符串,或如果子字符串需要 utf8 来表示,则表示未定义。
一个 utf8 字符串,分别表示任何匹配必须包含的锚定或浮动子字符串,或如果未找到此类子字符串,或如果子字符串仅包含 7 位 ASCII 字符,则表示未定义。
一个整数,从匹配位置开始的字符中的第一个偏移量,我们应该在该位置查找相应的子字符串。
一个整数,从匹配位置开始的字符中的最后一个偏移量,我们应该在该位置查找相应的子字符串。
对于锚定忽略,因此可以是 0 或与最小值相同。
FIXME:不确定这是什么,与后向查找有关。regcomp.c 说:当最终模式被编译并且数据从 scan_data_t 结构移动到 regexp 结构时,后向查找的信息被考虑在内,并且信息将丢失,预先计算在关联字符串的 end_shift 域中。
一个常量字符串,“anchored”、“floating”或“none”之一,表示应该首先检查哪个子字符串(如果有)。
字符类(“开始类”)的字符串表示,它必须是任何匹配的第一个字符。
TODO:解释表示。