我认为这段代码可以找到字符串的长度。这到底是怎么回事?

时间:2019-07-10 18:28:01

标签: regex perl

我的任务是将一些代码从Perl转换为Python,然后遇到了使我感到困惑的这段代码:

my $length = map $_, $root =~ /(.)/gs;

通过变量名和测试,我确定它可以获取字符串的长度,但这似乎是一种非常奇怪且难以理解的方法。有什么理由为什么有人会用它来代替this post中提到的length($root)或可怕的$root =~ y///c?我想确保我不会因为某些我不知道的奇怪Perl行为而丢失某些功能。

3 个答案:

答案 0 :(得分:3)

在列表上下文中,带有/ g修饰符的m //运算符返回所有捕获的列表,在这种情况下,该捕获是字符串中的每个字符。该映射是无操作的,但在标量上下文中返回它将在其生成的列表中包含的元素数,因此结果是字符串中的字符数。 m //运算符在标量上下文中的工作方式不同,因此需要此中间步骤。一个类似的习惯用法是:

[<function Foo.m1 at 0x1171e4e18>, <function Foo.m2 at 0x1171e4268>]

这通常用于更复杂的匹配计数,因为length函数非常适合且效率更高。

答案 1 :(得分:3)

我能想到的唯一区别是,在5.6.x损坏的Unicode模型下,length()返回字符数,而/(.)/gs返回字节数。从5.8.0开始,两者都返回字符数。 5.6.0是19年前发布的,而5.8.0是17年前发布的。

答案 2 :(得分:1)

我不确定原始编码者为什么采用这种“长”方法来获得$root的长度。

让我逐段剖析代码:

下面的代码将返回一个列表,其中包含$root中与.匹配的每个字符(基本上是每个字符)。

$root =~ /(.)/gs

然后映射生成的列表,这基本上什么也不做。在标量上下文中,map将返回元素数:

map $_, (list)

然后,此值存储在$length中。