Regex 使用Perl正则表达式获取URI的第二个字符串
我需要获取URI的第二部分,可能的URI是:Regex 使用Perl正则表达式获取URI的第二个字符串,regex,apache,perl,substring,uri,Regex,Apache,Perl,Substring,Uri,我需要获取URI的第二部分,可能的URI是: /api/application/v1/method /web/application/v1/method 我可以使用以下方法获取“应用程序”: ([^\/api]\w*) 及 但我知道这不是最好的办法,什么是好办法 谢谢 编辑:感谢大家的输入,我们的目标是使用重写规则将uri的第二部分设置到apache中的头中。通用正则表达式(Perl或PCRE语法)的解决方案是: ^/[^/]+/([^/]+) 每个部分都用/分隔,因此只需捕获尽可能多的非
/api/application/v1/method
/web/application/v1/method
我可以使用以下方法获取“应用程序”
:
([^\/api]\w*)
及
但我知道这不是最好的办法,什么是好办法
谢谢
编辑:感谢大家的输入,我们的目标是使用重写规则将uri的第二部分设置到apache中的头中。通用正则表达式(Perl或PCRE语法)的解决方案是:
^/[^/]+/([^/]+)
每个部分都用/
分隔,因此只需捕获尽可能多的非/
字符即可
这比非贪婪正则表达式更可取,因为它不需要回溯,并且允许节中可能包含的任何其他字符,这些字符可以很容易地包含非单词字符,例如-
,这些字符不会被\w
您的模式([^\/api]\w*)匹配
由一个捕获组和一个否定字符类组成,该字符类将首先匹配1次,而不是/
、a
、p
或i
。看
在此之后,将匹配0+次单词字符。例如,模式只能匹配字符类中未列出的单个字符
您可以使用捕获组并匹配\w+
^/(?:api|web)/(\w+)/v1/method
解释
字符串的开头^
非捕获组,可交替使用。匹配api或web(?:api | web)
- <代码>(\w+)捕获组1,匹配1+字字符
按照示例数据中的字面意思进行匹配/v1/method
我们有很多选择,不确定哪一个是最好的,但可以简单到:
\/(.+?)\/(.+?)\/.*
我们想要的输出在第二个捕获组$2
中
例子
#/usr/bin/perl-w
严格使用;
使用警告;
使用特征qw(例如);
main();
次干道{
我的$string='/api/application/v1/method
/web/application/v1/method';
我的$pattern='\/(.+?)\/(.+?)\/.';
my$match=replace($pattern,$2',$string);
比如说$match,“是所有正则表达式的匹配,我想提出其他方法
它们还只解析一个(URI样式)路径,如正则表达式路径,并返回第二个目录
- 最基本也是最有效的一个,就是
/
use URI;
my $dir = ( URI->new($path)->path_segments )[2];
split
首先返回'
(在第一个/
之前),因此我们需要第三个元素。(注意,我们可以为分隔符模式使用另一个分隔符,它是regex:split m{/},$path
)
- 例如,使用适当的模块
或
使用什么取决于您所做工作的细节——如果您对URL和web有任何其他工作,那么您显然希望使用模块;否则,它们可能(也可能不是)是一种过度使用
我已经对这些模块进行了基准测试,以检查人们使用模块支付的费用是否合理
split
或者比regex高出10-15%
(使用否定字符类的regex和基于非贪婪+?
的regex大致相同),或与它们大致相同。它们比Mojo
快约30%
,只有URI
严重滞后,落后Mojo
五倍
这是现实生活中URL的典型路径,有一些短组件。只有两个很长的字符串(10k个字符),Mojo::Path
(让我惊讶)比split
(!)领先六倍,比字符类regex领先一个数量级以上
对于这样长的字符串,求反的字符类regex将非贪婪(+?
)的性能提高了3倍,这一点很好理解
在所有这些中,URI和Mojo对象都是提前创建的
基准代码。我想指出,这些时间安排的细节远不如代码的结构和质量重要
Rate URI_path Mojo_path non_greedy neg_cc just_split
URI_path 146731/s -- -82% -87% -87% -89%
Mojo_path 834297/s 469% -- -24% -28% -36%
non_greedy 1098243/s 648% 32% -- -5% -16%
neg_cc 1158137/s 689% 39% 5% -- -11%
just_split 1308227/s 792% 57% 19% 13% --
在v5.16的笔记本电脑上运行(10秒)此打印
速率URI\u路径Mojo\u路径非贪婪neg\u cc just\u split
URI_路径146731/s--82%-87%-87%-89%
莫霍乌大道834297/s 469%--24%-28%-36%
非贪婪1098243/S648%32%--5%-16%
neg_cc 1158137/s 689%39%5%--11%
刚拆分1308227/s 792%57%19%13%--
我们应该记住,对于这样一个简单的作业,函数调用的开销非常大,尽管基准测试,但这些数字可能是最好的粗略指南。您用Perl标记了这一点,但这是Perl代码吗?因为在Perl中,最好的方法是使用模块,而不是正则表达式。请尝试/(?:api | web)/(\w+)/v1/method
这是一个URL;File::Spec不合适,但是URI和Mojo::URL会。@Grinnz-nah,除了去掉“URI”这个词之外,他们没有给我们任何提示,没有模式;他们要求正则表达式和所有答案,包括你的答案,只是解析一个路径(正确地说,这就是给出的全部内容)。顺便说一句,我在URI
(无论如何,这将是一个严重的过度杀伤力);对于Mojo也是如此。我专门去找了一些东西来支持模块的使用,最后得到了一个简单的ol'文件::Spec
(有点令人失望)。@Grinnz如果你知道一个模块可以在URI上下文中解析“主机”路径,并且很方便,我很乐意添加它。(或者如果我错过了URI
)@Grinnz我很好奇,你注意到最后一句话了吗(主要部分)在我的回答中?好的,前两个确实-,我解释了这只是关于解析路径,不是吗?我的回答是专门针对OP明确询问的URL路径。文件系统路径需要File::Spec提供的可移植性,例如(mo)
use URI;
my $dir = ( URI->new($path)->path_segments )[2];
use Mojo::Path;
my $dir = Mojo::Path->new($path)->parts->[1];
use warnings;
use strict;
use feature 'say';
use URI;
use Mojo::Path;
use Benchmark qw(cmpthese);
my $runfor = shift // 3; #/
#my $path = '/' . 'a' x 10_000 . '/' . 'X' x 10_000;
my $path = q(/api/app/v1/method);
my $uri = URI->new($path);
my $mojo = Mojo::Path->new($path);
sub neg_cc {
my ($dir) = $path =~ m{ [^/]+ / ([^/]+) }x; return $dir; #/
}
sub non_greedy {
my ($dir) = $path =~ m{ .+? / (.+?) (?:/|$) }x; return $dir; #/
}
sub URI_path {
my $dir = ( $uri->path_segments )[2]; return $dir;
}
sub Mojo_path {
my $dir = $mojo->parts->[1]; return $dir;
}
sub just_split {
my $dir = ( split /\//, $path )[2]; return $dir;
}
cmpthese( -$runfor, {
neg_cc => sub { neg_cc($path) },
non_greedy => sub { non_greedy($path) },
just_split => sub { just_split($path) },
URI_path => sub { URI_path($path) },
Mojo_path => sub { Mojo_path($path) },
});
Rate URI_path Mojo_path non_greedy neg_cc just_split
URI_path 146731/s -- -82% -87% -87% -89%
Mojo_path 834297/s 469% -- -24% -28% -36%
non_greedy 1098243/s 648% 32% -- -5% -16%
neg_cc 1158137/s 689% 39% 5% -- -11%
just_split 1308227/s 792% 57% 19% 13% --