最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

perl - Regex to extract one part of the URI - Stack Overflow

programmeradmin1浏览0评论

Here's the full URI:


I want to extract the base64 string after /view/ and before the numeric part in this case 366792786:

This is the part I'm trying to match:

TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z

I've managed to go this far:

my $uri = ";;
if ($uri =~ m/view\/(.+)\//g) {
    print $&;
}

But, it only produces the whole thing:

view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/

Please help me find the regex.

Here's the full URI:

https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4

I want to extract the base64 string after /view/ and before the numeric part in this case 366792786:

This is the part I'm trying to match:

TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z

I've managed to go this far:

my $uri = "https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4";
if ($uri =~ m/view\/(.+)\//g) {
    print $&;
}

But, it only produces the whole thing:

view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/

Please help me find the regex.

Share Improve this question edited Feb 2 at 12:04 toolic 62.2k20 gold badges79 silver badges127 bronze badges asked Feb 2 at 11:42 DanDan 911 silver badge8 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 5

You should use $1 instead of $& to capture what is in the capturing parentheses.

Also:

  • Do not use .+ because it grabs the slash. Use [^/]+ to grab all non-slash characters.
  • There is no need for the //g global modifier.
  • You can use alternate delimiters {} to avoid escaping the slash characters.

my $uri = "https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4";
if ($uri =~ m{view/([^/]+)}) {
    print $1;
}

Outputs:

TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z

I must have tested this originally with some different URL then added the long one from the answer. My initial answer makes no sense because the interesting piece of the answer is no longer interesting: that Mojo breaks up the path for you. If you can't use that feature, who cares? You're back to playing with a big string, neither has an advantage from

use v5.10;

my $url = "https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4";

use Mojo::URL;
my( $p1 ) = Mojo::URL->new($url)->fragment =~ m|/view/(.*?)/|;
say "Mojo: $p1";

use URI;
my( $p2 ) = URI->new($url)->fragment =~ m|/view/(.*?)/|;
say "URI: $p2";

Here's the answer that wasn't helpful and didn't work with the actual data:

A regex can be fine, but if you're already doing a lot of web stuff, a proper URL module can help. Mojo::URL is nice because it already breaks up the path components so you can look at them individually:

use v5.10;
use Mojo::URL;

my $url = "https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4";

my @parts = Mojo::URL->new($url)->path->parts;

my $last;
for (my $i=0; $i <= $#parts; $i++ ) {
    $last = $parts[$i] if $parts[$i-1] eq 'view';
    }

say $last;

This approach is nice when you need the other parts, such as the host, at the same time.

Here's the working example originally suggested by brian d foy:

    use Mojo::URL;
    use Data::Dumper;
    
    my $url = "https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4";
    
    my $fragment = Mojo::URL->new($url)->fragment;
    my @parts = $fragment =~ m{([^/]+)}g;
    
    print $parts[1];

You can do this more concisely than Mojo::URL, just using some Perl builtins:

use 5.036;

my $uri = 'https://example/entry/#/view/TCMaftR7cPYyC3q61TnI6_Mx8PwDTsnVyo9Z6nsXHDRzrN5ftuXxHN7NvIGK34-z/366792786/aHR0cHM6Ly9lcGwuaXJpY2EuZ292LmlyL0ltZWlBZnRlclJlZ2lzdGVyP2ltZWk9MzU5NzQ0MzkxMDc2Mjg4';
my @parts = split '/', $uri;

shift @parts while ($parts[0] && $parts[0] ne 'view');

my $frag = $parts[1];
say $frag;
发布评论

评论列表(0)

  1. 暂无评论