0

したがって、次のファイルのみを含む 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 が見つかり、完全に削除されます。だから私はここでロジックを見つけることができません。

4

4 に答える 4

4

substrの 3 番目のパラメーターは長さであり、終了インデックスではないため、 を渡す必要があり$to-$from+1ます。

(ただし、コードを調整して、 a<と a の両方が検出>され、>が の後にあることを確認する必要があり<ます。)

于 2013-07-28T10:28:04.527 に答える
4

s///次の演算子を使用できます。

$line =~ s/<[^>]+>//g
于 2013-07-28T09:44:02.310 に答える
3

単純な正規表現の置換は、サンプル データで必要な処理を行う必要がありますが、正規表現を使用して (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
于 2013-07-28T10:14:57.180 に答える
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>

出力:

カニエ・ウェスト
クリス・マーティン

一方、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>
于 2013-07-28T10:07:50.480 に答える