quotemeta EXPR
quotemeta

返回 EXPR 的值,其中所有 ASCII 非“单词”字符都已反斜杠转义。(也就是说,所有不匹配 /[A-Za-z_0-9]/ 的 ASCII 字符在返回的字符串中都会被加上反斜杠,无论任何区域设置。)这是在双引号字符串中实现 \Q 转义的内部函数。(有关非 ASCII 代码点的行为,请参见下文。)

如果省略 EXPR,则使用 $_.

quotemeta(以及 \Q ... \E)在将字符串插入正则表达式时很有用,因为默认情况下,插入的变量将被视为一个小型正则表达式。例如

my $sentence = 'The quick brown fox jumped over the lazy dog';
my $substring = 'quick.*?fox';
$sentence =~ s{$substring}{big bad wolf};

将导致 $sentence 变成 'The big bad wolf jumped over...'

另一方面

my $sentence = 'The quick brown fox jumped over the lazy dog';
my $substring = 'quick.*?fox';
$sentence =~ s{\Q$substring\E}{big bad wolf};

或者

my $sentence = 'The quick brown fox jumped over the lazy dog';
my $substring = 'quick.*?fox';
my $quoted_substring = quotemeta($substring);
$sentence =~ s{$quoted_substring}{big bad wolf};

两者都会保留句子不变。通常,当从用户那里接受文字字符串输入时,必须使用 quotemeta\Q

请注意,如果您在\Q\E之间放置了字面反斜杠(那些不在插值变量内部的反斜杠),双引号反斜杠插值可能会导致令人困惑的结果。如果您需要\Q...\E中使用字面反斜杠,请参阅"perlop 中关于解析引号构造的详细说明"

由于"\Q STRING \E"的结果对所有元字符进行了引用,因此无法在\Q\E对内插入字面$@。如果由\保护,$将被引用为"\\\$";如果没有,它将被解释为插值标量的开始。

在 Perl v5.14 中,所有非 ASCII 字符在非 UTF-8 编码的字符串中被引用,但在 UTF-8 字符串中不被引用。

从 Perl v5.16 开始,Perl 采用了一种 Unicode 定义的策略来引用非 ASCII 字符;ASCII 字符的引用保持不变。

同样保持不变的是,在use feature 'unicode_strings'作用域之外引用非 UTF-8 字符串的方式,即引用上拉丁 1 范围内的所有字符。这为不使用 Unicode 的旧程序提供了完全的向后兼容性。(请注意,unicode_stringsuse v5.12或更高版本的作用域内自动启用。)

use locale的作用域内,无论字符串是否编码为 UTF-8,所有非 ASCII 拉丁 1 代码点都会被引用。如上所述,locale 不会影响 ASCII 范围字符的引用。这可以防止在那些将"|"等字符视为单词字符的区域设置中出现问题。

否则,Perl 使用从 Unicode 调整后的方法来引用非 ASCII 字符(参见https://www.unicode.org/reports/tr31/)。唯一被引用的代码点是那些具有以下任何 Unicode 属性的代码点:Pattern_Syntax、Pattern_White_Space、White_Space、Default_Ignorable_Code_Point 或 General_Category=Control。

在这些属性中,重要的两个是 Pattern_Syntax 和 Pattern_White_Space。它们是由 Unicode 为决定正则表达式模式中哪些字符应该被引用而设置的。任何可以作为标识符的字符都没有这些属性。

Perl 保证,如果我们将来在已经定义的十几个正则表达式模式元字符(\ | ( ) [ { ^ $ * + ? .)中添加任何元字符,我们只会使用具有 Pattern_Syntax 属性的元字符。Perl 还保证,如果我们将来添加在正则表达式中被视为空格的字符(目前主要受/x影响),它们都将具有 Pattern_White_Space 属性。

Unicode 保证,具有这两个属性的代码点集永远不会改变,因此在 v5.16 中未被引用的内容在任何未来的 Perl 版本中都不需要被引用。(并非所有匹配 Pattern_Syntax 的代码点都实际分配了字符;因此还有增长空间,但无论是否分配,它们都会被引用。当然,Perl 永远不会使用未分配的代码点作为实际的元字符。)

引用具有其他 3 个属性的字符是为了提高正则表达式的可读性,而不是因为它们实际上需要被引用以用于正则表达式目的(具有 White_Space 属性的字符在页面或屏幕上可能与具有 Pattern_White_Space 属性的字符无法区分;另外两个属性包含非打印字符)。