【问题标题】:matching cond in perl using double exclaimation在 perl 中使用双重感叹匹配 cond
【发布时间】:2021-08-22 04:20:17
【问题描述】:
if ($a =~ m!^$var/!)

$var 是二维散列中的键,$a 是另一个散列中的键。

这句话是什么意思?

【问题讨论】:

标签: regex perl match


【解决方案1】:

这是一个regular expression(“正则表达式”),其中! 字符用作要在通过=~ operator(@987654328 @ 在这里)。

考虑使用相同的正则表达式与通常的分隔符,$a =~ /^$var\//(然后m 可能会被省略);但是现在显然必须转义模式中使用的任何/。为了避免这种难看和嘈杂的\/ 组合,人们经常使用另一个字符作为分隔符,因为几乎可以使用任何字符(我最喜欢的是卷曲,m{^$var/})。 §

问题中的这个正则表达式测试变量$a 中的值是否以(^ anchor)变量$var 的值开头,然后是/(评估变量并使用结果)。 §


变量名不是一个好的选择,因为 $a$b 被内置 sort 使用

提前准备好模式,甚至不需要分隔符

my $re = qr{^$var/};

if ($string =~ $re) ...

(但我仍然喜欢使用//,然后发现它更清晰)

上面我使用qr,但一个简单的q() 就可以了(虽然我绝对推荐qr)。这些也几乎可以使用任何字符作为分隔符。


§在模式内部,评估的变量被用作正则表达式模式,通常有什么问题(如果打算这样做,它们应该使用qr 编译并因此用作子模式)。

一个没有想象力的例子:一个变量$var = q(\s)(文字反斜杠后跟字母s)在一个模式内评估产生\s序列,然后将其视为一个正则表达式模式,用于空格。 (可能是无意的;我们只是想要\s。)

这可以通过使用quotemeta/\Q$var\E/ 来解决,这样$var 中可能的元字符就会被转义;这会产生正确的文字字符模式\\s。所以写模式的正确方法是m{^\Q$var\E/}

不这样做也会导致注入错误。感谢 ikegami 对此发表评论。

【讨论】:

  • :) - (但我不喜欢卷曲,因为量词。)
  • @AndyA。好吧:) 你的意思是它损害了可读性? (还能用——m{ (.{3}) }x ...)
  • OK - 也​​可以作为m{.{3}} 工作。而{} 量词并不常见,所以可能是最好的。蒂姆托迪
  • @AndyA。对,这就是我的意思——curlies 巢(请原谅我在示例中的(),我运行的一些奇怪的边缘案例测试的意外剩余)。绝对是口味问题,同意(嵌套除外,这比单字符分隔符具有事实上的优势)
【解决方案2】:

匹配运算符 (m/.../) 是 Perl 的“类引号”运算符之一。标准用法是在运算符中间的正则表达式之前和之后使用斜杠(如果使用斜杠,则可以从运算符的开头省略 m)。但是如果正则表达式本身包含一个斜杠,那么使用不同的分隔符来避免必须转义嵌入的斜杠是很方便的。在您的示例中,作者决定使用感叹号,但可以使用任何非空白字符。

许多 Perl 运算符都是这样工作的 - m/.../s/.../.../tr/.../.../q/.../qq/.../qr/.../qw/.../qx/.../(我可能忘记了一些)。

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 2012-03-06
    • 2012-07-07
    • 1970-01-01
    • 2011-05-29
    • 2012-04-20
    • 2019-02-13
    • 2021-11-02
    相关资源
    最近更新 更多