【问题标题】:What does |.*/|| do in Perl regex substitution?|.*/|| 是什么意思?在 Perl 正则表达式替换?
【发布时间】:2018-10-11 11:31:50
【问题描述】:

我正在将 Perl cgi 脚本转换为 Python。

在脚本中,我遇到了以下我不理解的代码。

帮我解决这个问题。

my $p = $0;
$p =~ s|.*/||;

我知道my $p = $0; 将脚本文件的绝对路径+名称分配给变量p

第二行将执行正则表达式替换,只给出不带路径的文件名。

但我不明白的是s之后的那些|.*/||

我搜索了很多资源,但不明白它的作用。

那些只给我脚本名称的事情实际上会做什么?

【问题讨论】:

  • |s 是s(替换)的分隔符,.*/ 表示直到最后一个/。它什么都没有。
  • 好吧好吧。现在我明白了。 :-)

标签: regex perl replace path substitution


【解决方案1】:

Perl 替换运算符如下所示:

s/PATTERN/STRING/

但它也是允许您选择自己的分隔符的 Perl 运算符之一。所以另一种写法是:

s|PATTERN|STRING|

这就是您在此处看到的版本。您的模式是.*/,替换字符串为空。因此,您的替换意味着“找到尽可能多的(非换行符)字符,后跟斜杠并将它们替换为空”。看看它上面一行中的赋值(它使用$0 - 程序的路径),看起来我们有代码从路径的前面删除目录并只留下文件名。

也就是说,如果您以程序名称/usr/local/bin/my_program 开头,那么$p 将最终只包含my_program

在 Perl 中编写它的更好方法是使用 File::Basename 模块。如果 Python 没有类似的东西,我会感到惊讶。

use File::Basename;

my $p = basename($0);

【讨论】:

  • 对最佳答案的旁注——$0 不会给出路径,而是“Contains the name of the program”。 (至少,不能保证给出路径。)它的问题是(我认为)它也不保证只返回名称:) 还有FindBin::$RealScript。 Python 中的一种方法是os.path.basename(__file__)
【解决方案2】:

鉴于特殊变量 $0 不包含换行符 - s|.*/|| 正则表达式实际上从您的字符串中删除最后一个(包括最后一个)/ 之前的 .*(所有内容)。因此,您可以剪切路径并仅保留文件名(之后最后一个 / 的所有内容)。

替换有不同的分隔符。它可以是s/// 或其他。无论如何,您需要了解perl substitution

仅供参考。 还要记住,.*? 表示non-greedy regexp。所以它将匹配第一个 / 之前的任何内容。

【讨论】:

  • @z0lupka $0 可以设置为任何值(因此,__FILE__ 在某些情况下可能是更好的选择,但 OP 中的用例尚不清楚)。 perl -E'$0 = "foo\nbar"; say $0'
  • @Grinnz., __FILE__ 也可以通过#line pragma 设置为任何内容
  • @ikegami 这需要一些黑魔法才能做到这一点,而对依赖它的代码来说并不明显(它也不太常见,通常用于修复__LINE__),而$0 可以随时被任何事物全局改变...
  • @Grinnz 您认为在编写具有明确定义的调用语义的 cgi-script 时考虑所有可能的条件是否有意义?当你确定你不使用像'$0 = "foo\nbar";`这样的淫秽预定义时
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2012-07-08
  • 2011-04-15
  • 2011-08-28
  • 1970-01-01
  • 2011-06-15
相关资源
最近更新 更多