I want to keep only the filenames (not full paths) and add the filename to some bbcode.
Here is the HTML to be converted:
<a href=/path/to/full/image.jpg rel=prettyPhoto><img rel=prettyPhoto src=/path/to/thumb/image.jpg /></a>
Notice I cannot have rel="foo" (no double quotes)..
Here is what I have in PERL, to perform the conversion:
s/\<a href=(.+?)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gi;
This converts the HTML to:
[box]/path/to/image.jpg[/box]
But this is what I want as a result:
[box]image.jpg[/box]
The HTML must remain the same. So how do I change my PERL so that $1 contains only the filename?
s/\<a href=(?:.*\/)?(.+?)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gi;
(?:.*\\/)?
Will match the longest part finishing by a /. The final ?
makes this optional.
I don't know if it handles fringe cases, but I got this to work:
#!/usr/bin/perl
use strict;
use warnings;
my $in = '<a href=/path/to/full/image.jpg rel=prettyPhoto><img rel=prettyPhoto src=/path/to/thumb/image.jpg /></a>';
$in =~ s/\<a href=.*?([^\/]+)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gi;
print $in . "\n";
However, wouldn't you rather do something like:
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TokeParser;
my $p = HTML::TokeParser->new(\*DATA);
my $token = $p->get_tag("a");
my $token_attribs = $token->[1];
my $bb_code;
if ($token_attribs->{rel} eq 'prettyPhoto') {
my $url = $token_attribs->{href};
my @split_path = split(m'/', $url);
$bb_code = '[box]' . $split_path[-1] . '[/box]';
}
print $bb_code . "\n";
__DATA__
<a href=/path/to/full/image.jpg rel=prettyPhoto><img rel=prettyPhoto src=/path/to/thumb/image.jpg /></a>
using an HTML parser (like HTML::TokeParser
, which has examples in the documentation) to find the url for you? Much better than relying on regexing the HTML by hand.
I suggest you use the right tools for the job, like these:
use HTML::PullParser;
use URI;
die '' . $! || $@
unless my $p = HTML::PullParser->new(
doc => $doc_handle
, start => 'tag, attr'
, report_tags => ['a']
);
my @file_names;
while ( my $t = $p->get_token ) {
next unless $t and my ( $tag_name, $attr ) = @$t;
next unless $attr and my $href = $attr->{href};
next unless my $uri = URI->new( $attr->{href} );
next unless my $path = $uri->path;
push @file_names, substr( $path, rindex( $path, '/' ) + 1 );
# or it's safe to use a regex here:
# push @file_names, $path =~ m{([^/]+)$};
}
Data::Dumper->Dump( [ \@file_names ], [ '*file_names' ] );
Don't capture the whole thing. Use non-capturing groups with (?:...)
. This way you can further subdivide the part that you match and the part that you capture.
这显然在正则表达式中不起作用,但是您可以在$ 1上运行split函数并获取结果数组的最后一个元素。
关于什么:
s/\<a href=.*\/(.+?)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gsi;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.