以下の広告を削除するフィルタを考えます。
Webページサンプル正直、ネタ切れなので細かな突っ込みはなしで。
例によって、[リンクのコピー -> ソースの表示 -> 検索] で該当ソースを検索します。
<p>
<a
href=
'http://sample.adserver.co.jp/'
>
[PR] 1000円からご希望のフィルタをお作りします!</a>
</p>
<p>
<a
href=
'http://test.adserver.co.jp/'
>
[PR] 2000円からご希望のフィルタをお作りします!</a>
</p>
おっと、失敗。
「視野を広く」でしたね。
Webページサンプル<div
class=
'htmlsrc_prx'
>
<div
class=
'ad'
>
<p>
<a
href=
'http://sample.adserver.co.jp/'
>
[PR] 1000円からご希望のフィルタをお作りします!</a>
</p>
<p>
<a
href=
'http://test.adserver.co.jp/'
>
[PR] 2000円からご希望のフィルタをお作りします!</a>
</p>
</div>
</div>
が怪しいですね。<div
class=
'ad'
>
div要素は単なるブロック要素ですが、class属性を付けることでスタイルシートで宣言したクラスを割り当てる事が出来ます。
"ad" は英語で「広告」の意。
従って、"ad" は広告専用のクラスと考えることが出来そうです。
(本来なら、他に "ad" のクラスが割り当てられている要素を探して、「広告専用のクラスであるか」を確かめるべきですが、今回はサンプルなので省略します。)
ここまで解れば、後は簡単。
広告はdiv要素の内にあるので、まとめて削除してしまいましょう。
[Patterns] Name = "Kill div ad type1" Active = TRUE URL = "$TYPE(htm)" Limit = 256 Match = "$NEST(<div\sclass=$AV(ad),</div>)" Replace = "\r\n<script type="comment"> Killed div ad </script>\r\n"
検索表現については、今までの学習から理解できると思いますので省略します。
置換テキストに見慣れない記述がありますね。
script要素はスクリプトを埋め込むための要素ですが、今回はイレギュラーな手口を使っています。
script要素はtype属性によって、「MIMEタイプ」を指定します。
MIMEタイプとは、かいつまんで言えば、「ファイルの内容」を指し示すものです。
今回はtype属性に "comment" を指定しましたが、実は "comment" というMIMEタイプは存在しません。
存在しないMIMEタイプを指定すると、ブラウザは内容を理解せず、「ないもの」として扱います。
つまり、コメントと同じ扱いとなります。
コメントは見やすく便利ですが、状況によっては既存のコメントを不正に閉じてしまうことがあります。
script要素によるコメントは複雑ですが、コメントを不正に閉じてしまう事はないため、汎用的なフィルタには多く使われています。
(コメントで囲まれた広告削除では、「元々コメントがあるところにコメントを残すので、不正にコメントを閉じてしまう場合はないだろう」との計算がありました。)
それでは、最終チェックです。
テストウインドウにてチェックした後に、このページの再読み込みによるテストを行って下さい。
今度は、スタイルシートを使った表現を考えてみましょう。
スタイルシートとは「文字の装飾, 余白」など、文書の見栄えを定義するためのものです。
スタイルシートの display: none を使うと、指定した要素を表示しないようにする事が出来ます。
( display: none
は子要素を含めて、不可視にします。)
<div
style=
'display: none'
class='ad'
>
<p>
<a
href=
'http://sample.adserver.co.jp/'
>
[PR] 1000円からご希望のフィルタをお作りします!</a>
</p>
<p>
<a
href=
'http://test.adserver.co.jp/'
>
[PR] 2000円からご希望のフィルタをお作りします!</a>
</p>
</div>
上のような形になれば良いわけです。
Kill div ad type2[Patterns] Name = "Kill div ad type2" Active = TRUE URL = "$TYPE(htm)" Limit = 256 Match = "<div(\s[^>]++class=$AV(ad))\0" Replace = "<div style='display: none'\0"
\0
はローカル変数と呼ばれるメタキャラクタです。
変数とは文字列を格納するための機構で、括弧で括った範囲を \0
に格納しています。
そして、格納した文字列を置換テキストで出力しているわけです。
これは
のように、class属性以外に属性を持っていてもマッチするという点で有効に働きます。<div
align=
'center'
class='ad'
>
変数はProxomitronを使う上で、とても重要な要素なので、是非この機会に覚えて下さい。
このように、変数は格納した文字列をそのまま使えるという点で便利です。
でも、よくよく考えてみると、格納した文字列を「同じ場所」に出力しているのですから、無駄な処理をしているようにも思えますね。
この場合は、肯定先読みを使う方法もあります。
肯定先読みは文字列を消費しないで、後述の文字列を先読みします。
要は、
があれば良いわけで、わざわざ消費する必要はなく、先読みするだけで十分事足ります。class=
'ad'
この場合は、消費しているのは <div
のみ、という事になります。
[Patterns] Name = "Kill div ad type3" Active = TRUE URL = "$TYPE(htm)" Limit = 128 Match = "<div(^(^\s[^>]++class=$AV(ad)))" Replace = "<div style='display: none'"
Limitはほとんど要らないので、初期値の半分の "128" にしました。("64" でも良いかもしれません。)
\s[^>]++class=$AV(ad)
を消費しなかったために、置換テキストがスッキリしましたね。
の手法は、長所と短所の2つを持ち合わせているので、上手く使い分ける必要があります。style=
'display: none'
詳しくは、display を参考にしてください。