如何使用 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])'
既然你用 macos 标记了问题,我想像
这样的简单 sed
命令没有问题
echo "$s" | sed -n 's,.*/d/\([^/]*\).*,,p'
匹配 /d/
之前的所有字符,捕获下一个字符,直到第一个 /
或字符串结尾,然后匹配其余字符。替换为第一组的内容并只打印该值。
我目前有一个字符串:
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])'
既然你用 macos 标记了问题,我想像
这样的简单sed
命令没有问题
echo "$s" | sed -n 's,.*/d/\([^/]*\).*,,p'
匹配 /d/
之前的所有字符,捕获下一个字符,直到第一个 /
或字符串结尾,然后匹配其余字符。替换为第一组的内容并只打印该值。