这种搜索在Perl中是如何工作的?

这种搜索在Perl中是如何工作的?,perl,Perl,@匹配存储一些子字符串。此代码从@匹配项中捕获最长的子字符串,然后将其存储在$longest中 源代码: my ($len, $longest) =0; length > $len and ($longest, $len)=($_, length) for @matches; 这看起来几乎是故意混淆的。这里有一个更详细的表达相同的逻辑 #!usr/bin/perl use strict; use Data::Dumper; my $needle = "axibidm"; my $ha

@匹配
存储一些子字符串。此代码从
@匹配项中捕获最长的子字符串,然后将其存储在
$longest

源代码:

my ($len, $longest) =0;
length > $len and ($longest, $len)=($_, length) for @matches;

这看起来几乎是故意混淆的。这里有一个更详细的表达相同的逻辑

#!usr/bin/perl

use strict;
use Data::Dumper;

my $needle = "axibidm";
my $haystack = "axididm";
my @matches;


for my $start (0..length $needle) {
for my $len (1 .. ((length $needle)-$start)) {
    my $substr = substr($needle, $start, $len);
       push @matches, $haystack =~ m[($substr)]g;
    print "$substr\t";
    print "@matches\t\n";
  }
}

my ($len, $longest) = 0;

length > $len and ($longest, $len) = ($_, length) for @matches;


print "The longest common substring between\n", $needle, "\nand\n", $haystack, "\nis '$longest'\n";
让我们来比较一下

my $len = 0;
my $longest;

foreach my $match (@matches) {
  if (length($match) > $len) {
    $longest = $match;
    $len = length($match);
  }
}
这声明了两个词法(
my
)变量
$len
$longest
,并将第一个(
$len
)设置为0,将
$longest
保留为其默认值
未定义

这一结构:

my ($len, $longest) = 0;
与此相同:

 (code goes here) for @matches;
因此,我们在
@matches
数组上迭代,并对每个元素运行一次代码。在代码体中,特殊变量
$\uu
将保存当前元素

 for (@matches) {
     (code goes here)
 }
首先,
(表达式)和(代码)
是书写
if((表达式)){(代码)}
的简写方式。这是因为在Perl中,
是以短路方式从左到右计算的。也就是说,如果左侧表达式为false,Perl不需要计算右侧表达式,因为它的值无关紧要
false和
任何东西都是
false

如果在没有参数的情况下调用
length
,则表示
length($\u)
,因此这是正在检查的
@matches
的当前元素的长度


($var1,$var2)=($val1,$val2)
是一种并行赋值,它将
$var1
设置为
$val1
,将
$var2
设置为
$val2

,看起来几乎是故意混淆的。这里有一个更详细的表达相同的逻辑

#!usr/bin/perl

use strict;
use Data::Dumper;

my $needle = "axibidm";
my $haystack = "axididm";
my @matches;


for my $start (0..length $needle) {
for my $len (1 .. ((length $needle)-$start)) {
    my $substr = substr($needle, $start, $len);
       push @matches, $haystack =~ m[($substr)]g;
    print "$substr\t";
    print "@matches\t\n";
  }
}

my ($len, $longest) = 0;

length > $len and ($longest, $len) = ($_, length) for @matches;


print "The longest common substring between\n", $needle, "\nand\n", $haystack, "\nis '$longest'\n";
让我们来比较一下

my $len = 0;
my $longest;

foreach my $match (@matches) {
  if (length($match) > $len) {
    $longest = $match;
    $len = length($match);
  }
}
这声明了两个词法(
my
)变量
$len
$longest
,并将第一个(
$len
)设置为0,将
$longest
保留为其默认值
未定义

这一结构:

my ($len, $longest) = 0;
与此相同:

 (code goes here) for @matches;
因此,我们在
@matches
数组上迭代,并对每个元素运行一次代码。在代码体中,特殊变量
$\uu
将保存当前元素

 for (@matches) {
     (code goes here)
 }
首先,
(表达式)和(代码)
是书写
if((表达式)){(代码)}
的简写方式。这是因为在Perl中,
是以短路方式从左到右计算的。也就是说,如果左侧表达式为false,Perl不需要计算右侧表达式,因为它的值无关紧要
false和
任何东西都是
false

如果在没有参数的情况下调用
length
,则表示
length($\u)
,因此这是正在检查的
@matches
的当前元素的长度


($var1,$var2)=($val1,$val2)
是一种并行赋值,它将
$var1
设置为
$val1
,将
$var2
设置为
$val2

有人太聪明了,或者他们打错了。或者两者兼而有之。可能两者都有

这段代码中有一些事情并没有完成它看起来要做的事情。这不会将两个变量都初始化为零

length > $len and ($longest, $len) = ($_, length);
这是一种欺骗的写作方式

my ($len, $longest) = 0;
对于$matches
是愚蠢的,只有一件事需要迭代,那么为什么要使用循环呢?这个习惯用法偶尔被用于将值放入
$\uuu
中,并在各种默认构造中使用它,但在这里没有多大用处

接下来,下面是一种非常复杂的编写
的方法,如果这样做的话就这样做
。这样写是为了使它成为一个表达式,它将在for循环语句修饰符中工作

my $len = 0;
my $longest;
这样写好多了

length > $len and ($longest, $len)=($_, length)
扩展它,删除无用的for循环,我们得到

if( length > $len ) {
    $longest = $_;
    $len = length;
}

另一个选项是
$matches
是一个数组引用,它们的意思是@$matches
<$matches的code>仍然可以“工作”,但它总是返回21的长度,因为数组引用将字符串化为类似于
数组(0x7fc07c800468)
有人太聪明了,或者他们输入了一个错误。或者两者兼而有之。可能两者都有

这段代码中有一些事情并没有完成它看起来要做的事情。这不会将两个变量都初始化为零

length > $len and ($longest, $len) = ($_, length);
这是一种欺骗的写作方式

my ($len, $longest) = 0;
对于$matches
是愚蠢的,只有一件事需要迭代,那么为什么要使用循环呢?这个习惯用法偶尔被用于将值放入
$\uuu
中,并在各种默认构造中使用它,但在这里没有多大用处

接下来,下面是一种非常复杂的编写
的方法,如果这样做的话就这样做
。这样写是为了使它成为一个表达式,它将在for循环语句修饰符中工作

my $len = 0;
my $longest;
这样写好多了

length > $len and ($longest, $len)=($_, length)
扩展它,删除无用的for循环,我们得到

if( length > $len ) {
    $longest = $_;
    $len = length;
}
另一个选项是
$matches
是一个数组引用,它们的意思是@$matches
<$matches的code>仍将“起作用”,但它将始终返回21的长度,因为数组引用字符串化为类似于
数组(0x7fc07c800468)

大致与

EXPR for LIST;
EXPR1 and EXPR2;
( $x, $y ) = ( EXPR1, EXPR2 )

大致与

EXPR for LIST;
EXPR1 and EXPR2;
( $x, $y ) = ( EXPR1, EXPR2 )
(这不是普遍接受的做法,除非
EXPR2
是流量控制表达式(
next
die
等)


length
默认使用
$\u
作为其参数(
length($\u)


大致与

EXPR for LIST;
EXPR1 and EXPR2;
( $x, $y ) = ( EXPR1, EXPR2 )
(一个显著的区别是,您可以使用
($x,$y)=($y,$x)
来交换值,但这里使用了这种方法。)

(在两个标量赋值可以的情况下使用列表赋值也不是普遍接受的做法。)


编写代码的一种更为传统的方法是:

$x = EXPR1;
$y = EXPR2;
大致与

EXPR for LIST;
EXPR1 and EXPR2;
( $x, $y ) = ( EXPR1, EXPR2 )

大致相同