以下 Perl 语句的含义是什么?
($script = $0) =~ s#^.*/##g;
我正试图理解 operator =~ 以及右侧的语句 s#^.*/##g。
谢谢
以下 Perl 语句的含义是什么?
($script = $0) =~ s#^.*/##g;
我正试图理解 operator =~ 以及右侧的语句 s#^.*/##g。
谢谢
=~
将右边的东西(模式匹配或搜索和替换)应用到左边的东西上。有很多关于 =~
的文档,所以我只是要指向一个相当不错的文档。($copy = $original) =~ s/foo/bar/;
这是一种将变量复制并在单个步骤中执行搜索和替换的方法。它等效于:
$copy = $original;
$copy =~ s/foo/bar/;
=~
操作符对左边的内容进行操作,该内容为左手代码运行后的结果。($copy = $original)
的值为$copy
,因此=~
会对副本进行操作。
s#^.*/##g
与s/^.*\///g
相同,只是使用可替代定界符来避免倾斜的牙签综合症。您几乎可以使用任何字符作为正则表达式定界符。 #
很常见,虽然我认为它难看且难以阅读。 我更喜欢{}
,因为它们平衡。s{^.*/}{}g
是等效的代码。$script = $0;
$script =~ s{^.*/}{}g;
$0
是脚本的名称。以下代码将复制脚本名称并除去最后一个斜杠之前的所有内容(.*
贪婪匹配,尽可能匹配多)。它仅获取脚本文件名。
/g
表示在字符串上执行尽可能多次的匹配。由于这只能匹配一次(^
将其锚定在字符串开头),所以它没有任何作用。
有一种更好、更安全的方法可以做到这一点。
use File::Basename;
$script = basename($0);
=~
到底是做什么的。 - ysth=~
运算符,但我已经修改了以涵盖它。 - Schwern非常简单:
Perl的引号类似表达式可以使用许多不同的字符作为分隔符。命令后面的分隔符(在本例中是s
)是其余操作的分隔符。例如:
# Out with the "Old" and "In" with the new
$string =~ s/old/new/;
$string =~ s#old#new#;
$string =~ s(old)(new);
$string =~ s@old@new@;
new
字符串替换old
字符串。不论在s
后面跟什么分隔符,这个替换操作都会生效。需要注意的是,圆括号、花括号和方括号使用配对。这对于可以代替单引号和双引号的q
和qq
非常方便:print "The value of \$foo is \"foo\"\n"; # A bit hard to read
print qq/The value of \$foo is "$foo"\n/; # Maybe slashes weren't a great choice...
print qq(The value of \$foo is "$foo"\n); # Very nice and clean!
print qq(The value of \$foo is (believe it or not) "$foo"\n); #Still works!
上述代码仍然有效,因为引号运算符会计算开放和关闭括号。当然,在正则表达式中,括号和方括号是正则表达式语法的一部分,因此您不会在替换中经常看到它们。
大多数时候,强烈建议您坚持使用s/.../.../
形式,这样更易于阅读。这是人们所习惯的,并且易于理解。但是,如果你遇到了这种情况呢?
$bin_dir =~ s/\/home\/([^\/]+)\/bin/\/Users\/$1\bin/;
那些反斜杠可能会使阅读变得困难,因此传统做法是用其他分隔符替换反斜杠分隔符,以避免产生“山丘和山谷效应”。
$bin_dir =~ s#/home/([^/]+)/bin#/Users/$1/bin#;
^
、*
、|
和+
都是神奇的正则表达式字符,并且可能会在正则表达式中使用,#
是常用的一个。它在字符串中不常见,在正则表达式中也没有任何特殊含义,因此不会被使用。($script = $0) =~ s#^.*/##g;
等同于:
($script = $0) =~ s/^.*\///g;
由于原始程序员不想使用反引号来转义斜杠,所以他们更改了分隔符。
至于:
($script = $0) =~ s#^.*/##g;`
它的意思和以下语句相同:
$script = $0;
$script =~ s#^.*/##g;
$script
的赋值和替换。这在Perl中很常见,但一开始可能有点难理解。use File::Basename;
...
$script = basename($0);
更易读且易于理解 -- 即使对于老练的 Perl 程序员也是如此。
$script
变量分配为$0
的内容(包含调用脚本名称的字符串)。=〜
字符是绑定操作符。它调用正则表达式匹配或正则表达式搜索和替换。在这种情况下,它与新变量$script
匹配。s
字符表示搜索和替换正则表达式。#
字符用作正则表达式的分隔符。正则表达式模式引号字符通常是/
字符,但您可以使用其他字符,包括此处的#
。^.*/
。它的意思是“在字符串开始,搜索零个或多个字符,直到斜杠。这将在每行上继续捕获,除了换行符(默认情况下不匹配.
)。#
表示“替换”值的起点。通常,在此处有一个模式,该模式使用第一行中的任何捕获部分。#
。这结束了替换模式。由于在替换模式的开始和结束之间没有任何内容,因此将找到的第一个内容替换为无。g
,或全局匹配。搜索和替换将根据它在值中的匹配次数而不断发生。有效地,搜索并清空值中/之前的每个值,但保留所有换行符,在脚本名称中。它是一种非常懒惰的方式,可以在仅适用于类unix路径的长脚本中调用脚本名称。
如果有机会,请考虑使用Perl中的核心模块File :: Basename
进行替换:
use File::Basename;
# later ...
my $script = fileparse($0);
=~
是绑定(不是匹配)运算符。 - Michael Carman
perl -de0
)? - Jim Garrison