当我尝试使用Perl的substr提取git repo URL时,为什么我会得到额外的?

时间:2014-10-16 20:11:51

标签: perl

所以我从一个相当简单的代码片段中得到了一些奇怪的行为。我不太清楚为什么会这样。看起来这两个片段应该做同样的事情:

my $s = "some-package    [git://github.com/repo/some-package]";
$s = substr($s, 0, length($s)-1);
$s = substr($s, index($s, "[")+1);
print $s . "\n";

my $s = "some-package    [git://github.com/repo/some-package]";
$s = substr($s, index($s, "[")+1, length($s)-1);
print $s . "\n";

但这些是我得到的每一段代码的结果:

git://github.com/repo/some-package

git://github.com/repo/some-package]

不太确定为什么第二个代码段不会删除最后一个字符。

3 个答案:

答案 0 :(得分:2)

substr的第三个参数是长度,而不是索引。因此,请考虑字符串'abcde'b的索引为1。您想从c开始,因此起始位置为2。字符串的长度为5。从中减去1以获得4。因此,

$s = 'abcde';
substr($s, index($s, 'b') + 1, length($s) - 1);

转换为

substr($s, 2, 4)

你需要的是

my $s = "some-package    [git://github.com/repo/some-package]";
my $i = index($s, '[') + 1;
say substr($s, $i, length($s) - $i - 1);

您也可以使用split

my $s = "some-package    [git://github.com/repo/some-package]";
say split(qr{ \S+ \s+ \[ | \] }x, $s);

答案 1 :(得分:1)

在你的第二个片段中,你要求给你太多的字符:你开始从位置index($s, "[")+1获得一个子字符串,但要求给你多少length($s)-1个字符(例如"some-package [git://....]"个字符的长度{1}}工作人员减1)。您应该改为length($s)-index($s, "[")-2

my $s = "some-package    [git://github.com/repo/some-package]";
$s = substr($s, index($s, "[")+1, length($s)-index($s, "[")-2);
print $s . "\n";

但实际上你应该只使用正则表达式来完成这些任务。

if ($s =~ m|\[(git://.*?)\]|) {
    my $repo = $1;
    print "$repo\n";
}

答案 2 :(得分:1)

这是使用Perl正则表达式的理想场所。

你想找到两个括号之间的字符串,对吗?所以这就是你做的。

my $s = "some-package    [git://github.com/repo/some-package]";
if ( $s =~ /\[(.+)\]/ ) {
    my $repo = $1;
}
else {
    die "Couldn't find a string between two brackets";
}

网上有许多优秀的正则表达式教程可以帮助您入门。一旦你使用正则表达式进行字符串解析,你就会想知道你是如何使用index + substr的。