perl substr删除字符串中两个位置之间的所有内容

时间:2013-07-28 09:26:01

标签: perl indexing substr

所以我有这个文件clip.txt只包含:

<a href="https://en.wikipedia.org/wiki/Kanye_West">Kanye West</a>, 
<a href="http://en.wikipedia.org/wiki/Chris_Martin">Chris Martin</a>

现在我想删除&lt; ...&gt;之间的所有内容所以我最终得到了

Kanye West,Christ Martin。

使用perl我有当前代码:

#!/usr/local/bin/perl

$file = 'clip.txt';
open(FILE, $file);
@lines = <FILE>;
close(FILE);
$line =  @lines[0];

while (index($line, "<") != -1) {
my $from = rindex($line, "<");
my $to = rindex($line, ">");

print $from;
print ' - ';
print $to;
print ' ';

print substr($line, $from, $to+1);
print '|'; // to see where the line stops
print "\n";
substr($line, $from, $to+1) = ""; //removes between lines
$counter += 1;

}

print $line;

所有“打印”行都相当冗余,但很适合调试。

现在结果变成:

138 - 141 </a>
|
67 - 125 <a href="http://http://en.wikipedia.org/wiki/Chris_Martin">Chris Martin|
61 - 64 </a>, |
0 - 50 <a href="https://en.wikipedia.org/wiki/Kanye_West">|
Kanye West

首先脚本在138 -141之间找到位置,然后将其删除。 然后它找到67 - 125但它删除67 - 137。 接下来它找到61-64,但它删除了61-66。

为什么这样做? 在底线找到0 - 64,它完全删除。所以我在这里找不到逻辑。

4 个答案:

答案 0 :(得分:4)

您可以使用s///运算符:

$line =~ s/<[^>]+>//g

答案 1 :(得分:4)

substr的第三个参数是长度,而不是结束索引,因此您应该传递$to-$from+1

(尽管您还应该调整代码以确保它找到<>,并且>位于<之后。)< / p>

答案 2 :(得分:3)

正确的解决方案确实是使用HTML::TokeParser::Simple之类的东西。但是,如果您只是将此作为学习练习,您可以通过提取您想要的内容来简化它,而不是删除您不想要的内容:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

while (my $line = <DATA>) {
    my $x = index $line, '>';
    next unless ++$x;
    my $y = index $line, '<', $x;
    next unless $y >= 0;
    say substr($line, $x, $y - $x);
}

__DATA__
<a href="https://en.wikipedia.org/wiki/Kanye_West">Kanye West</a>,
<a href="http://en.wikipedia.org/wiki/Chris_Martin">Chris Martin</a>

输出:

Kanye West
Chris Martin

另一方面,使用HTML解析器并不是那么复杂:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

use HTML::TokeParser::Simple;

my $parser = HTML::TokeParser::Simple->new(\*DATA);

while (my $anchor = $parser->get_tag('a')) {
    my $text = $parser->get_text('/a');
    say $text;
}

__DATA__
<a href="https://en.wikipedia.org/wiki/Kanye_West">Kanye West</a>,
<a href="http://en.wikipedia.org/wiki/Chris_Martin">Chris Martin</a>

答案 3 :(得分:3)

虽然简单的正则表达式替换应该在示例数据上执行您想要的操作parsing (X)HTML with regexes is generally a bad idea(并且使用简单字符搜索执行相同的操作基本相同)。更灵活,更易读的方法是使用正确的HTML解析器。

Mojo::DOM示例:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';
use Mojo::DOM;

# slurp data into a parser object
my $dom = Mojo::DOM->new(do { local $/; <DATA> });

# iterate all links
for my $link ($dom->find('a')->each) {

    # print the link text
    say $link->text;
}

__DATA__
<a href="https://en.wikipedia.org/wiki/Kanye_West">Kanye West</a>, 
<a href="http://en.wikipedia.org/wiki/Chris_Martin">Chris Martin</a>

输出:

Kanye West
Chris Martin