0

私のフォーラムでは、外部サイトへのリンクにrel="nofollow"を自動的に追加したいと考えています。たとえば、誰かが次のテキストで投稿を作成します。

Link 1: <a href="http://www.external1.com" target="_blank">External Link 1</A>
Link 2: <a href="http://www.myforum.com">Local Link 1</A>
Link 3: <a href="http://www.external2.com">External Link 2</A>
Link 4: <a href="http://www.myforum.com/test" ALT="Local">Local Link 2</A>

Perl を使用して、次のように変更します。

Link 1: <a href="http://www.external1.com" target="_blank" rel="nofollow">External Link 1</A>
Link 2: <a href="http://www.myforum.com">Local Link 1</A>
Link 3: <a href="http://www.external2.com" rel="nofollow">External Link 2</A>
Link 4: <a href="http://www.myforum.com/test" ALT="Local">Local Link 2</A>

かなりの数行のコードを使用してこれを行うことができますが、1 つまたは複数の正規表現でこれを行うことができることを望んでいました。しかし、私は方法を理解できません。

4

2 に答える 2

1

正規表現は限られたシナリオで機能しますが、正規表現を使用して HTML を解析しないでください

正規表現で HTML を解析しようとするたびに、邪悪な子供が処女の血を泣き叫び、ロシアのハッカーが Web アプリケーションを pwn します。

    — XHTML 自己完結型タグを除く RegEx 一致開始タグから

私は Mojo スイートを非常に気に入っています。これにより、ごくわずかなコードで適切なパーサーを使用できるからです。CSS セレクターを使用して、興味深い要素を見つけることができます。

use strict; use warnings;
use autodie;
use Mojo;
use File::Slurp;

for my $filename (@ARGV) {
  my $dom = Mojo::DOM->new(scalar read_file $filename);

  for my $link ($dom->find('a[href]')->each) {
    $link->attr(rel => 'nofollow')
      if $link->attr('href') !~ m(\Ahttps?://www[.]myforum[.]com(?:/|\z));
  }

  write_file "$filename~", "$dom";
  rename "$filename~" => $filename;
}

呼び出し:perl mark-links-as-nofollow.pl *.htmlデータに対してテストを実行すると、次の出力が生成されます。

Link 1: <a href="http://www.external1.com" rel="nofollow" target="_blank">External Link 1</a>
Link 2: <a href="http://www.myforum.com">Local Link 1</a>
Link 3: <a href="http://www.external2.com" rel="nofollow">External Link 2</a>
Link 4: <a alt="Local" href="http://www.myforum.com/test">Local Link 2</a>

なぜ一時ファイルと を使用したのrenameですか? ほとんどのファイル システムでは、ファイルの名前をアトミックに変更できますが、ファイルへの書き込みには時間がかかります。そのため、他のプロセスが半分書き込まれたファイルを参照する可能性があります。

于 2013-09-04T08:38:41.613 に答える