Regex 使用Perl正则表达式获取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语法)的解决方案是: ^/[^/]+/([^/]+) 每个部分都用/分隔,因此只需捕获尽可能多的非

我需要获取URI的第二部分,可能的URI是:

/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% --