如何使用 perl 在不应用两次的情况下提取文本,向前看和向后看字符串?

How to use perl to extract text between and look ahead and a look behind string without applying it twice?

我目前有一个字符串:

https://drive.google.com/file/d/j2903r293rj092j3r20/view?usp=sharing

我想从中提取 j2903r293rj092j3r20。我在 Mac OS 中使用标准的 perl 安装。我有

URL="https://drive.google.com/file/d/j2903r293rj092j3r20/view?usp=sharing"
echo $URL | perl -pe 's/https\:\/\/drive.google.com\/file\/d\///g' | perl -pe 's/\/view\?usp=sharing//g'

我在前面和后面应用perl。有没有一种方法可以一步完成?谢谢

你可以把这两部分用逗号分隔在一个 perl -pe 命令中:

echo $URL | perl -pe 's/https\:\/\/drive.google.com\/file\/d\///g','s/\/view\?usp=sharing//g'

当然可以。

首先,这里使用替换运算符(s/.../.../)是错误的工具。您可以使用匹配运算符 (m/.../) 来提取您想要的字符串的位。

echo $URL | perl -pe 'm/https\:\/\/drive.google.com\/file\/d\/(\w+)/ and $_ = '

在这里,我们使用“捕获括号”将URL中/d/后面的“单词字符”(字母数字和下划线)字符串复制到变量</code>。然后我们将其复制到 <code>$_ 中,因为这是 -p 将自动打印的变量。

但我们可以做得更好。 s/.../.../m/.../ 都允许我们更改分隔符,这样我们就不必转义所有这些斜线。

echo $URL | perl -pe 'm[https://drive.google.com/file/d/(\w+)] and $_ = '

我们可以直接使用print来去掉末尾有点混乱的变量赋值。

echo $URL | perl -ne 'print m[https://drive.google.com/file/d/(\w+)]'

而且,如果我们知道我们的输入数据总是看起来像当前示例,那么就真的没有必要包含这么多 URL。

echo $URL | perl -ne 'print m[/d/(\w+)]'

更新: 你有一条评论建议你使用 URI module 来解析你的字符串。我不认为这特别有用,因为该模块将为您提供 URL 的路径部分,您仍然需要提取路径的正确部分。但是,为了完整起见,这里有一个使用该模块的示例:

echo $URL | perl -MURI -ne 'print +(URI->new($_)->path_segments)[3]'

我们根据输入创建一个 URI 对象,并立即调用其 path_segments() 方法来获取路径段。我们打印返回列表的第四个元素。

解析 URL 时最好使用合适的解析器,例如 URI

use strict;
use warnings;
use URI;

my $uri = URI->new("https://drive.google.com/file/d/j2903r293rj092j3r20/view?usp=sharing");
my @path = $uri->path_segments;
print $path[-2];

这会打印:

j2903r293rj092j3r20

我想如果你在 one-liner 中需要这个,它应该是这样的:

perl -MURI -lne'$u = URI->new($_); print (( $u->path_segments )[-2])'

既然你用 标记了问题,我想像

这样的简单 sed 命令没有问题
echo "$s" | sed -n 's,.*/d/\([^/]*\).*,,p'

匹配 /d/ 之前的所有字符,捕获下一个字符,直到第一个 / 或字符串结尾,然后匹配其余字符。替换为第一组的内容并只打印该值。