在"Programming Perl"中,"你无法隐藏正则表达式结构中模式的终止分隔符"是什么意思?

use*_*860 3 regex perl

抱歉,我再次需要帮助来理解"编程Perl"一书中相当复杂的片段.在这里(对我来说,标记为粗体的是什么模糊):

模式被解析为双引号字符串,所有正常的双引号约定都可以使用,包括变量插值(除非您使用单引号作为分隔符)和使用反斜杠转义符表示的特殊字符.这些是在将字符串解释为正则表达式之前应用的(这是Perl语言中少数几个字符串经过多次处理的地方之一)....

这种双遍解析的另一个结果是普通的Perl tokener首先找到正则表达式的结尾,就好像它正在寻找普通字符串的终止分隔符一样.只有在找到字符串的结尾(并完成任何变​​量插值)之后,才将模式视为正则表达式.除此之外,这意味着你不能"隐藏"正则表达式构造中的模式的终止分隔符(例如括号中的字符类或正则表达式注释,我们尚未涉及).Perl将在任何地方看到分隔符并在该点终止模式.

首先,为什么说它Only after it has found the end of the string不像the end of the regular expression以前所说的那样?

第二,这是什么意思you can’t “hide” the terminating delimiter of a pattern inside a regex construct?为什么我无法隐藏终止分隔符/,而我可以将它放在regexp中直接/A\/C/或插入变量中的任何位置(即使没有\):

my $s = 'A/';
my $p = 'A/C';
say $p =~ /$s/;
Run Code Online (Sandbox Code Playgroud)

输出1.

当我写作并重新阅读我的问题时,我认为这个片段讲述了使用单引号作为正则表达式分隔符,然后它们似乎都非常有凝聚力.我的假设是否正确?

我的赞赏.

cjm*_*cjm 7

它表示"字符串的结尾"而不是"正则表达式的结尾",因为在那一点上它正在将正则表达式视为只是一个字符串.

它试图说这不起作用:

/foo[-/_]/
Run Code Online (Sandbox Code Playgroud)

尽管普通的正则表达式元字符在内部并不特殊[],但Perl会将正则表达式视为/foo[-/并且抱怨未终止的类.

它试图说Perl在读取它时不解析正则表达式.首先,它在源代码中找到正则表达式的结尾,就好像它是一个带引号的字符串,所以唯一的特殊字符是\.然后它插入任何变量. 然后它将结果解析为正则表达式.

您可以隐藏终止分隔符,\因为它适用于普通字符串.您可以在插值变量中隐藏分隔符,因为在找到分隔符后会发生插值.如果你使用包围分隔符(例如{ }[ ]),你可以在正则表达式中嵌套匹配的分隔符对,因为q{}也是这样的.但你无法将其隐藏在任何其他正则表达式构造中.

  • @caligula:不要自欺欺人.Perl解析是复杂的东西.很复杂,除了perl`之外几乎没有任何东西可以100%正确.这种语言是由语言学爱好者制作的,他们通常更喜欢语法,因为它易于解析. (2认同)

ike*_*ami 5

假设你想匹配一个*.你会用的

m/\*/
Run Code Online (Sandbox Code Playgroud)

但是,如果你使用你*作为分隔符怎么办?以下不起作用:

m*\**
Run Code Online (Sandbox Code Playgroud)

因为它被解释为

m/*/
Run Code Online (Sandbox Code Playgroud)

如下所示:

$ perl -e'm*\**'
Quantifier follows nothing in regex; marked by <-- HERE in m/* <-- HERE / at -e line 1.
Run Code Online (Sandbox Code Playgroud)

取字符串文字

"a\"b"
Run Code Online (Sandbox Code Playgroud)

它产生字符串

a"b
Run Code Online (Sandbox Code Playgroud)

同样,匹配运算符

m*a\*b*
Run Code Online (Sandbox Code Playgroud)

产生正则表达式

a*b
Run Code Online (Sandbox Code Playgroud)

如果要匹配文字*,则必须使用其他方法.换一种说法.

m*a\*b*      ===  m/a*b/       matches pattern a*b
m*a\x{2A}b*  ===  m/a\*b/      matches pattern a\*b
Run Code Online (Sandbox Code Playgroud)