繁体   English   中英

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

[英]perl substr remove everything between two positions in string

所以我有这个文件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>

现在我想删除<...>之间的所有内容,以便最终得到

坎耶·韦斯特,克里斯汀·马丁。

与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,并且完美删除。 所以我在这里找不到逻辑。

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

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

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

(尽管您还应该调整代码以确保它同时找到<和a > ,并且>< 。)

正确的解决方案确实是使用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>

尽管可以使用简单的正则表达式替换来完成示例数据上的操作,但是使用正则表达式解析(X)HTML通常不是一个好主意 (并且通过简单的字符搜索执行相同的操作基本上是相同的)。 一种更灵活,更易读的方法是使用适当的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM