nlFilterの文法一覧
このページは移転作業中です。見づらい点がありますが、ご了承ください。
nlFilter (単にフィルタとも) とは、NicoCache_nl に搭載された機能のひとつで、Java の正規表現を用いてページの書き換えを行う機能です。
フィルタの作成
適切な記述を行ったテキストファイルを、NicoCache_nl をインストールしたフォルダ (jar と同じフォルダ) にある "nlFilters" フォルダに設置することで、フィルタとして読み込ませることができます。
インストール時から存在しているファイルを書き換えた場合、バージョンアップ時に上書きされ変更点が消えてしまう可能性があるので、新規にファイルを作成してそちらに追加することをオススメします。なお、その際の文字コードは UTF-8 (BOM なし) にして以下の 1 行を最初の行に書き、2 行目からフィルタの内容を書くようにしてください。
# nlフィルタ定義(文字コード判定用なのでこの行は削除しないこと)
なお、厳密なフィルタの適用順は以下のようになっています。
nlFilter_sys.txt → nl 本体内蔵 → Extension → nlFilters フォルダ内 (ファイル名順) → nl 本体のフォルダにあるnlFilter.txt
※ログに出てくる順番に適用されるので、詳しくはそちらを参照してください。
フィルタの書式
詳しくは既存のフィルタを参照してください。
簡単なフィルタの例
[Replace] Name = サンプルフィルタ URL = (?:www|seiga)\.nicovideo\.jp ContentType = text/html Match< (動|静)画 > Replace< $1$1画 >
このフィルタを適用 (テキストファイルに追記) すると、ニコニコ動画 (www.nicovideo.jp) とニコニコ静画 (seiga.nicovideo.jp) の「動画」というテキストがすべて「動動画」に、「静画」が同じく「静静画」に置き換えられます。
解説すると、以下のような構成になっています。
[Replace] → フィルタの種類 (通常の置き換え) Name = サンプルフィルタ → フィルタの名前 URL = (?:www|seiga)\.nicovideo\.jp → フィルタの適用先 URL (正規表現、"http://" の部分を除いた前方一致) ContentType = text/html → フィルタを適用するコンテンツタイプ (今回は HTML ドキュメントのみに適用) Match< (動|静)画 > → 検索テキストを指定 (正規表現利用可能、"Match<" 〜 ">" まで) Replace< $1$1画 > → 置き換えテキストを指定 ( $1 〜 $9 でグループの参照が可能、"$" のものを含めたい場合は "\$" とする)
フィルタの種類
[Replace] - 通常のフィルタ
通常のフィルタです。
ここをコメントアウト (先頭に # をつける、つまり "[Replace]" を "#[Replace]" にする) と、そのフィルタは無効になります。
[RequestHeader] - リクエストヘッダフィルタ
サーバへ要求する際のヘッダの置換を行う。現状では URL の置き換えのみが可能なようです。
主に /local 以下のファイルへのリダイレクトに使用します。
[Debug] - デバッグ
通常利用することはほとんどありません。フィルタ定義の外に "[Debug]" とだけ書いた行を置いておくと、処理した URL・マッチしたフィルタ名・置換を行ったかどうかがログに表示されます。
そのままだと、デフォルトのフィルタが多数表示されるので、調べたいフィルタだけにすると楽です。(が、他のフィルタとの干渉は調べられなくなります…)
また、ニコニコ以外のサイトでフィルタを使用したときは、文字コードが判別できずにスルーされたアドレスも表示されます。
[Config] - 開発者用
通常利用することはほとんどありません。
"[Config]" で設定したパラメータは、EasyRewriter 内の以下のメソッドで読み出せます。
public static JavaPattern[] getMatch(String name) public static String[] getReplace(String name) public static Pattern getURL(String name)
name はフィルタ名、対応するフィルタが無い時は null を返します。使い方としては以下のようになります。
JavaPattern[] pattern = EasyRewriter.getMatch("movieCommentMatch"); if (pattern != null) { JavaMatcher matcher = pattern[0].matcher(content); }
EachLine を使用した場合は、1 行目から順に pattern[0] 〜 に対応し、使用していない場合は pattern[0] となります。
Extension などで読むようにしておくと、フィルタに設定するだけで仕様変更に対応できるかも…?
フィルタの設定項目
Name - フィルタの名前
Name = ◯◯置き換えフィルタ
フィルタの名前を設定します。(ログに表示されます)
URL - フィルタを適用する URL
URL = www\.nicovideo\.jp/watch/
フィルタを適用する URL を設定します。
URLは "http://" 以降から、正規表現の前方一致でマッチするアドレスを探します。
なお、URL フィールドの値の先頭に POST/ を付けると、通常とは逆に POST するデータに対してフィルタを適用できます。
URL = POST/www\.nicovideo\.jp/watch/
Multi - グローバルマッチ指定
Multi = TRUE
" Multi = TRUE " とすると、ページ内で見つかった物すべてを置換 (グローバルマッチ) します。 " Multi = FALSE " とするかまたは省略すると、最初に見つかった物だけを置換します。
EachLine - 各行置換指定
EachLine = TRUE Match< ニコニコ動画 ニコニコ生放送 > Replace< NICONICO VIDEO ニコ生 > → 「ニコニコ動画」は「NICONICO VIDEO」に、「ニコニコ生放送」は「ニコ生」に置き換えられる
" EachLine = TRUE "とすると、"Match" と "Replace" の一行ずつを一組として、それぞれ置換を行います。 ひとつのフィルタで複数種類の置換を行う時に使用します。
" EachLine = FALSE " とするかまたは省略すれば、"Match" と "Replace" が改行してあっても一組として動作します。 そのとき "Replace" 内の改行は無視されず、そのまま改行として反映されます。
Require
「Require = 正規表現」で指定した正規表現が含まれる場合に置換を行います。
「Require = !正規表現」で指定した正規表現が含まれない場合に置換を行います。
つまり、通常の正規表現を書けば、それがページ中でマッチした場合のみ置換されます。
先頭に"!"をつけると、"!"を除いた部分にマッチしなかった時のみ置換されます。
複数の条件をORで指定する場合、Require = !hoge1|hoge2|hoge3|....になります。(hoge1,hoge2,hoge3は正規表現)
ANDで指定する場合、先読みアサーションでRequire = !\A(?=[\S\s]*hoge1)[\S\s]*hoge2のように指定します。
idGroup
キャッシュが存在した時のみ置換するフィルタです。
ID取得用に、idGroupに動画ID(sm~)、サムネID(数字部分のみ)への参照番号を","区切りで指定します。
"idGroup = 1,2"とすれば、$1,$2が参照され、キャッシュがあれば置換されます。
また、"Replace"中にセパレータとして"<$>"を入れる事で、キャッシュが通常/エコノミーで"Replace"のパターンを変えることが出来ます。
"<$>"以前が通常キャッシュ用、以後がエコノミーキャッシュ用となります。
改行は入れなくても良いし、EachLineで使用することも出来ます。
"<$>"が無いときは通常/エコノミーで同じ置換が行われます。
IDを2つ指定しているのは、マイメモリやチャンネルで数字のみ10桁の動画IDの時、サムネIDから検索して表示するためです。
リンクの色変えなどでIDが1つしかない時は、1つだけ指定することも可能です。
NicoCache_nl+101219mod以降
→以下のように文字列中に埋め込む事ができます(従来の記述も有効です)
Replace< $0<div style="position:relative;"> <img src="http://www.nicovideo.jp/local/cache<icon$economy>.gif" ~> </div> >
$の左右に\w+が存在した場合は<>前後の文字列と連結します
片方が空白文字の場合も有効、\w以外の文字があると認識しません
また、同一Replace中に複数の記述はできません
Match
置換させたい場所を正規表現で書きます。
「Match<」の次の行から、ページ内の置換元になる正規表現を書きます。
"EachLine = FALSE" の時は、改行は無視されるので注意してください。
改行にマッチさせるには「\s*」で吸収するか、「\r\n」を明示的に指定する必要があります。
置換元の記述は、「>」とだけ書かれた行で終了します。
Replace
結果の出力の仕方を書きます。
「Replace<」の次の行から、置換先の文章を書きます。
"Match"内で「( )」(指定したグループ)を使用していれば、"Replace"で"$1"、"$2"の様に参照することができます。
"$0"を指定すると、"Match"でマッチした部分すべてを参照出来ます。
Matchと同じく、「>」とだけ書かれた行で終了します。
RequireHeader
NicoCache_nl+101219mod以降
→特定のUser-Agentやuser_sessionに限定できます(Requireのリクエストヘッダ版)
ex) RequireHeader = user_session_12345678_\d+
上手く記述すればログインユーザー毎にnlFilterを切り換えることができるかも
ContentType
NicoCache_nl+101219mod以降
→特定のContent-Typeに限定できます(部分一致する正規表現を記述)
ex) ContentType = text/(?:html|xml)
※指定した場合、Conetnt-Typeが無い場合にマッチしなくなるので注意
NicoCache_nl+110522mod以降
否定条件(行頭の'!')を使えるようにした
ex) ContentType = !text/(?:html|xml)
MatchLocal
NicoCache_nl+101219mod以降
→URL = www\.nicovideo\.jp/ と記述した場合に、このオプションをTRUEにすると/local/以下にもマッチするようになります(FALSEならマッチしません)
※よって、MatchLocalオプションの記述が無い既存フィルタはマッチしません
URL = www\.nicovideo\.jp/local/ と/local/以下まで記述した場合は、MatchLocalの値に関わらず常にマッチします
AddList
NicoCache_nl+101219mod以降
→nlFilterからLSTファイルにReplaceの内容を追加できます(動作仕様はAPIと同じ)
ex) AddList = list/NGUserId.txt
※このオプションを指定した場合、コンテンツの内容は書き換えません
AddVariable
NicoCache_nl+101219mod以降
→URL固有の変数にReplaceの内容を保存して、他のフィルタから参照できます
ex) AddVariable = foo
同じ変数に対して複数追加する場合は文字列が連結されます
他のフィルタから参照するにはReplaceに「<nlVar:foo>」と書きます
※このオプションを指定した場合、コンテンツの内容は書き換えません
コマンド
$NEST
$NEST(開始タグ,コンテンツマッチ条件,終了タグ)
開始タグ、終了タグは、前方参照「( )」を含まない正規表現を使います。
コンテンツマッチ条件は開始タグと終了タグを除く部分に"部分マッチ"する正規表現をつかいます。
また、オミトロンと違いマッチする最も"内側の"タグが範囲となります。
「$NEST」は単体でしか書けません。
(9).10から、コンテンツマッチ条件内のグループへの前方参照ができるようになりました。
例:$NEST(<script ,web_pc_top_bottom,</script>)
$LST
$LST("ファイル名")
(9).10で追加されたコマンド、(9).10aにて仕様変更。 ""に囲まれたファイルを読み込んで、中身を行単位で"|"でつないだ物を"()"でグループ化して返します。 ""は必須です。"()"でグループ化するので、自動的に前方参照が一つ追加されることになります。 そのままだと、ファイルの内容はエスケープされますが、$LST("!ファイル名") の様に"!"をつけることで、エスケープせずに正規表現として渡すことが出来ます。 (!で始まる名前のファイルは使用できません。) また、"#start"とのみ書かれた行以降がリストとして読み込まれ、それ以前の部分・改行のみの行は無視されます。 リストの先頭の行がnlFilterと同様の"# nlフィルタ定義"で始まっていれば、自動的に文字コードを判定します。それ以外ならシステムのデフォルトの文字コードで読み込みます。 リストは動的更新が可能です。更新されたときは自動的に読み込まれます。
例:$LST("!local/ngword.txt")
local/ngword.txt: # nlフィルタ定義(文字コード判定用なのでこの行は削除しないこと) #start (?:ニ[コフ]){2}動画 fz\d+ so\d+
NicoCache_nl+110110mod以降
→#startの記述を不要に&一つでも空$LSTが含まれる場合は置換処理をスキップ
副作用で行頭が'#'の正規表現を書く場合は'\'でエスケープする必要があります
$LSTが空の時は"(?!)"に置換します
$LSTのファイル名指定で""(ダブルクォート)を省略できるようになりました
"!"を付けなければエスケープ無し、"!"を付けるとエスケープになりました
NicoCache_nl+110522mod以降
Match以外の正規表現が記述できる場所(Requireとか)でも$LSTを使えるようにした
$INC
NicoCache_nl+110110mod以降
nlFilterでマッチした回数を参照できます
→Match内に「$INC(NGCount)」と書くとReplaceで「<nlVar:NGCount>」として参照できます
$INCはマッチした場合に指定した変数の値をインクリメントします
変数が存在しない場合は0で初期化してからインクリメントします
変数が既に存在してかつ数値として評価できない場合はエラーになります
$INC自体は除去してからマッチングを行うのでMatch内の任意の位置に記述できます
$SET
NicoCache_nl+110110mod以降
nlFilterでマッチした時に変数を設定できます
→Match内に「$SET(name=value)」と書くとマッチした時に変数に値を設定できます
※現状、オミトロンと異なりvalue部分は固定値しか書くことはできません
$TS
NicoCache_nl+110604mod以降
[Replace]フィルタのみ有効です([RequestHeader]で使えても意味が無いので)
-
引数にローカルファイル(NicoCacheフォルダからの相対パス)を指定すると、引数にファイル更新時刻文字列(='?'+UNIXTIME)を付加して置換します
$TS(local/popThumb.js) → local/popThumb.js?1298081651
$TS(local/nicoplayer.swf?ts=) → local/nicoplayer.swf?ts=1239336522
-
引数のローカルファイルが存在しない場合、引数そのものに置換します
$TS(local/nonexistent.json) → local/nonexistent.json
-
引数を指定しない場合、現在時刻文字列(=UNIXTIME)に置換します
var replacedTime = "$TS()"; → var replacedTime = "1306132319";
※基本はsrc指定におけるブラウザキャッシュ避け用途を想定していますが、JavaScript内に置けば通信せずにファイルの有無と更新時刻を取得できます
$URL
Match内で使用する「()」を使うグループ化のURL版です。
例えば
URL = www\.nicovideo\.jp/mylist/(\d+)
となっていると
Replace内で「$URL1」を使うことで、(\d+)の部分を参照する事が出来ます。
NicoCache_nl+101219mod以降
Replaceで「$URL0」も置換するようになりました
変数
フィルタの「Replace」内で使用すると、置換時に各変数に置き換えられます。
<id>
watchページで使用可。"sm~"、"nm~"などの"~"(数字部分)に置換されます。
<smid>
watchページで使用可。"sm~"、"nm~"などに置換されます。
<memoryId>
watchページで使用可。マイメモリーでは"0123456789"のようなマイメモリーIDに、通常再生では"sm~"などの動画IDに置換されます。
<freeSpace>
http://www.nicovideo.jp内で使用可。"12.34"(GB単位)のようなキャッシュドライブの空き容量に置換されます。
NicoCache_nl+101219mod以降
Replaceで「<freeSpace>」をいつでも使えるようになりました
<eachSmid>
idGroupを指定したときのみ有効。sm~形式のIDに置換されます。
<CRLF>
NicoCache_nl+101219mod以降
Replaceで「<CRLF>」を使うと改行コードに置換します
→EachLine = TRUE の時でも改行できるようになります
<nlVar:config!name>
NicoCache_nl+110110mod以降
nlFilterでconfig.propertiesの値を参照でます
→Replaceに「<nlVar:config!name>」と書くとconfigのnameという値を参照できます
$SETと組み合わせることで、nlFilterにあらかじめデフォルト値を書いておき、config.propertiesに値がある場合はそちらを優先する、という使い方ができます
ex) Match< $SET(config!nlFilterA.useFunction=false) </head> > Replace< <script type="text/javascript"><!-- var nlFilterA = { useFunction: <nlVar:config!nlFilterA.useFunction> }; //--></script> </head> >
※$SETを書かないとconfigに値が存在しない場合は置換処理されないので注意
<nlVar:VERSION>
NicoCache_nl+110122mod以降
Replaceで「<nlVar:VERSION>」を使うとバージョン文字列に置換します
コメント
#
「#」が先頭に使われている行はコメント行となり、その行はフィルタに反映されません。
フィルタサンプル
普通のフィルタ
プレミアム未登録などの記述を消す。
[Replace] Name = Test Filter (Remove Payment Status) URL = www.nicovideo.jp Multi = FALSE Match< :<strong>\s*<a[^>]+>プレミアム(?:未登録|\(月額\))</a>\s*</strong>\s*です > Replace< >
EachLine付きのフィルタ
「最近見た動画」を「最近見た気がする動画」に、「ニコニコ」を「にこニコ」に置換する。
[Replace] Name = Test Filter (EachLineつき) URL = www.nicovideo.jp/mylist EachLine = TRUE Multi = TRUE Match< (最近見た)(動画) ニコ(ニコ) > Replace< $1気がする$2 にこ$1 >
$NEST使用
watchの「ニコニコ市場とは・・・」の説明文を消す。
[Replace] Name = Delete Ichiba Description URL = www.nicovideo.jp/watch/ Multi = FALSE Match< $NEST(<table ,ニコニコ市場とは,</table>) > Replace< >
[RequestHeader]
旧プレイヤーへのアクセスを/local/oldplayer/以下にリダイレクトさせる。
[RequestHeader] Name = Redirect Old Player URL = www\.dummy\.com EachLine = True Match< http://([^/]+)/swf/nicoplayer\.swf(\?.*)? http://([^/]+)/swf/marqueeplayer\.swf(\?.*)? http://([^/]+)/swf/flv_bgmplayer\.swf(\?.*)? http://([^/]+)/swf/swf_bgmplayer\.swf(\?.*)? http://([^/]+)/swf/hirobaplayer\.swf(\?.*)? http://([^/]+)/swf/hirobamovie\.swf(\?.*)? > Replace< http://$1/local/oldplayer/nicoplayer.swf http://$1/local/oldplayer/marqueeplayer.swf http://$1/local/oldplayer/flv_bgmplayer.swf http://$1/local/oldplayer/swf_bgmplayer.swf http://$1/local/oldplayer/hirobaplayer.swf http://$1/local/oldplayer/hirobamovie.swf >