如何使用PERL正则表达式将文件名(不是完整路径)转换为$ 1

时间:2011-03-03 15:22:09

标签: regex perl bbcode

我想只保留文件名(不是完整路径)并将文件名添加到某个bbcode。

以下是要转换的HTML:

<a href=/path/to/full/image.jpg rel=prettyPhoto><img rel=prettyPhoto src=/path/to/thumb/image.jpg /></a>

注意我不能有rel =“foo”(没有双引号)..

以下是我在PERL中执行转换的内容:

s/\<a href=(.+?)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gi;

这会将HTML转换为:

[box]/path/to/image.jpg[/box]

但这就是我想要的结果:

[box]image.jpg[/box]

HTML必须保持不变。那么如何更改PERL以便$ 1只包含文件名?

6 个答案:

答案 0 :(得分:1)

s/\<a href=(?:.*\/)?(.+?)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gi;

(?:.*\/)?

将最长的部分匹配为/。最终?使这个可选。

答案 1 :(得分:1)

我不知道它是否会处理边缘情况,但我让它工作:

#!/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";

但是,你宁愿做一些像:

#!/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>

使用HTML解析器(如HTML::TokeParser,其中包含文档中的示例)为您找到网址?比依靠手工重新制作HTML要好得多。

答案 2 :(得分:1)

我建议您使用正确的工具,例如:

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' ] );

Friends don't let friends parse HTML with regexes.

答案 3 :(得分:0)

不要抓住整件事。使用(?:...)的非捕获组。这样,您可以进一步细分匹配的零件和捕获的零件。

答案 4 :(得分:0)

这显然在正则表达式中不起作用,但您可以在$ 1上运行split函数并获取结果数组的最后一个元素。

答案 5 :(得分:0)

怎么样:

s/\<a href=.*\/(.+?)\ rel=prettyPhoto\>\<img rel=prettyPhoto src=(.+?) \/>\<\/a\>/\[box\]$1\[\/box\]/gsi;
相关问题