Replace = "a$CONFIRM(b?)b$CONFIRM(c?)c" まず「a」を置換する。 "b?"というダイアログ出現。 | ├─「いいえ」を選択するとそこで置換終了。 | (二回目のダイアログは出ない) └─「はい」を選択すると「b」を置換する。 "c?"というダイアログ出現。 | ├─「いいえ」を選択するとそこで置換終了。 | └─「はい」を選択すると「c」を置換する。
使用可能な場所 : URL Match を除く検索表現、置換テキスト
引数は不要
$STOP()を使用すると、そのフィルター(cfgファイル全体ではない)が、その通信で、二度と使用されなくなる。高速化・誤爆の回避に使用する。
置換後ストップ、マッチしなければストップのように使う。
置換部分に入れる場合で、置換テキストにおける条件分岐が存在しない場合、入れ忘れないように、最初に入れておいた方が良い。
$STOP(all)、$STOP(*) の様にして、全てのフィルタを使用しないようにするなどという事は出来ない。
使用可能な場所 : HTTP-Header の検索表現・置換テキスト
booleanは、true か false のどちらか
Webページフィルタを実行するかしないかのスイッチ
スイッチはその接続でのみ有効
※4.5の場合、$FILTER(true) を使用しても、Webページフィルタが有効にならない事がある → 各バージョンの違い#v4-5june6-bug
使用可能な場所 : 置換テキスト
現在の接続を切断する。
HTTP-Header で使用された場合、./html/killed.html の内容(デフォルトは空白ページ)に書き換えられる。
また画像の場合 ./html/killed.gif (デフォルトは小さい透過画像)に置換される。
どちらも、Location: で変更されるのではなく、透過的に置換される。
Patterns で使用された場合、\k が出た所までブラウザに送信され、残りは送信されない。また、接続も切断されるので、通信の節約にもなる。
使用可能な場所 : 検索表現・置換テキスト
textは置換テキスト扱い
textがログウインドウに表示される。
text中の\t\r\nは無視される \xは使用可能
頭の一文字は特別で、文字の色として扱われる。
例えば、$LOG(Rtext) で、 text と表示される。
B = Blue
C = Cyan 実際はaqua
G = Green 実際はlime
R = Red
V = Violet 実際はfuchsia
Y = Yellow
w = gray 実際は#b4b4b4
これ以外の文字の場合、白文字になる。(大文字小文字を区別するので注意)
また、4.5では、頭に「!」を置くと、ログウインドウが強制的に表示される。
例:$LOG(!Rtext)
使用可能な場所 : 置換テキスト
any textは置換テキスト扱い
any text を1byteごとに%xx(xxは16進数2桁)に変換する。 ただし、以下の文字は除外されそのまま返される。
* + - . / : @ _ 0-9 A-Z a-z 0x00
1byteごとの検査であるので、例えば ヌ ( 0x83 , 0x6B ) は %83k を返す。
使用可能な場所 : 置換テキスト
any textは置換テキスト扱い
any text のうち、%xx(xxは16進数2桁)を元の文字に変換する。 対象となるのは%21-%7Eであり、それ以外の文字はそのまま返される。 完全には$ESC()の逆関数になっていない。
使用可能な場所 : 置換テキスト
any textは置換テキスト扱い
any text のうち、以下の文字の直前に \ ( 0x5C ) を付加して返す。
"(0x22) &(0x26) '(0x27) ((0x28) )(0x29) *(0x2A) +(0x2B) ?(0x3F) [(0x5B) \(0x5C) ](0x5D) |(0x7C)
1byteごとの検査であるので ゼゾ ( 0x83 , 0x5B , 0x83 , 0x5D ) に対して ソ[ソ] ( 0x83 , 0x5C , 0x5B , 0x83 , 0x5C , 0x5D ) を返す。 これを利用したのが以下のようなフィルタ。
[Patterns] Name = "Shift_JIS dameji escaper (test only)" Active = FALSE Limit = 20000 Match = "\1" Replace = "$WESC(\1)"
検索表現や置換テキストにおいて日本語を使いたい場合に、 このフィルタのTESTモードでテストをすれば良い。 Shift_JISだと2byte目が [ , \ , ] , | ( 0x5B , 0x5C , 0x5D , 0x7C ) である場合があり、それが原因でフィルタが動作しないことがあるがそれを防ぐ事が出来る。 ただし対象はShift_JISのみであり、フィルタエディタ部分を日本語使用可能にしている必要がある。
使用可能な場所 : 検索表現
matchは検索表現扱い
HTMLタグの属性値(Attribute's Value)にマッチするように作られたコマンド。
$AV(*) という表現は "*'|\w に等しい。つまり、
にマッチする。ここまでは$AVQと共通である。
($AV(\1))\2 という表現で、\1にはクォートを含まない属性値、\2にはクォートを含む属性値が格納される。ただし、属性値の囲みが " なのか ' なのかもしくは何も無いのかを判別するのは困難であり、その必要がある場合は$AVQを使うと良い。
$AV、$AVQ共に属性値内の\によるエスケープを考慮するので非常に使い勝手は良いが、どちらのコマンドも属性値に日本語が含まれる場合に誤マッチを引き起こす事があるので注意が必要である。
Bounds = "<img\s*>" Match = "*\salt=$AV(\1)*"
このような表現において\1にはalt属性の値が格納されるわけであるが、もし
<img alt="機能" src="aaa.jpg">
このような(Shift_JISの)文字列が与えられた場合、\1に格納されるのは「機能" src=」である。「能」の2byte目が \ (0x5C) に等しいため、日本語を理解できないproxomitronには
<img alt="□□□\" src="aaa.jpg">
このように見えてしまうからである。
解決策は時と場合により、この場合はalt値内にクォートの入れ子がありえないと見切りをつければ以下のような書き換えで対応できる。
Bounds = "<img\s*>" Match = "*\salt=(\"\1\"|'\1'|(\w)\1)*"
$AV内の最後がグループで、候補が複数ある場合、(例:「$AV(*.jp([eg]|eg))」や「$AV(a|b|c)」など)
グループ内の候補の順番に注意が必要なことがある。
例: $AV(*.jp(e|eg))> の場合、「a.jpe>」にはマッチするが、「a.jpeg>」にはマッチしない。 ※「*.jp(e|eg)>」は両方にマッチする。 ※「$AV(*.jp(eg|e))>」は両方にマッチする。
4.3、4.4、4.5May、4.5June、4.5June338で確認 仕様(バグ)らしい $AVQでも同じ
他候補の頭から途中、までのみの候補がある場合、短い候補は後ろにまわす必要がある。
javascript内に記述されたHTMLタグにマッチさせる場合は以下のバグに注意。
属性値が \" で囲まれている場合に起きるバグ。 テキスト: <test a=\"1\" b=2> Match欄 : a=$AV(\0) → 「\"1\"」がマッチ。 Match欄 : a=$AV(\0["]) → 「合致なし」 この場合、$AV()内の最後に ["] や \" を置くとマッチしなくなる。 $AVQ()でも同じ。( 4.5June338で確認 )
$AV(*) は以下の表現と同じ文字列にマッチする。
(["'])\9
(\\\\|\\$TST(\9)|?)++
$TST(\9)(^[!-=?-%FF])
|
[!-=?-%FF]+{1,*}
使用可能な場所 : 検索表現
matchは検索表現扱い
$AVとほとんど同様のコマンドなのでそちらを参照のこと。
唯一の違いとして、($AVQ(\1))\2 という表現では\1、\2共にクォートを含む属性値が格納される。よって、
$AVQ((\"|'|)*)
という表現をベースに属性値の囲みによって処理を振り分けられる。
start match、inner matchでは {x,y} の形での繰り返し回数指定が使えない。
{x} の形は動く。 end matchではどちらも動く。
例、テキスト "abc" でテストした場合。
$NEST(a,b,c) → マッチ
$NEST(a+{1},b,c) → マッチ
$NEST(a+{1,1},b,c) → 『合致なし』
$NEST(a+{1,*},b,c) → 『合致なし』
$NEST(a,b+{1},c) → マッチ
$NEST(a,b+{1,*},c) → 『合致なし』
$NEST(a,b,c+{1,*}) → マッチ
start match、end matchは外側と内側の両方にマッチするものでなければならないが、外側と内側で属性等が異なる場合で、その属性等も検索表現に含めたい時は、次項の$INESTか、肯定先読みを使う。
例: <div id="ad"><div>〜</div></div> に外側のid属性を指定してマッチさせたい場合 (^(^<div id=$AV(ad)))$NEST(<div,</div>) ※ 先読みで属性のマッチを行い、$NESTのstart matchは最低限にすることで、内外の属性の差異に関わらず入れ子を正しく認識できる。
>$NEST(<a\s,</a>) は <a\s*</a> よりも高速に動作する、という事です。 これ、\sの直後に*が来てるから後者が遅いだけじゃないか? $NEST(<a(\s*|)>,</a>) と <a(\s*|)>*</a> 検索対象=「<a hoge>url</a>aaaaaaaaaaaaaaaaaaaaaaaaa」を100個並べた物 だと逆転する。どっちにしろ誤差の範囲内だが。
end match は "$INESTコマンドの後ろに続く検索表現" に前方一致でマッチする 検索表現でなければ機能せず、『合致なし』となる。 ※ ここでは$INESTの動作条件のみに焦点を絞って書いてます。$INESTの正しい使い方は日本語訳ヘルプをご覧下さい。
× <table>$INEST(<a\s*>,</a>)</table> → "</a>" という検索表現は "</table>" にはマッチしない。 ○ <table>$INEST(<tab>,</tab*>)</table> → "</tab*>" という検索表現は "</table>" にマッチする。
使用可能な場所 : [HTTP Headers]の検索表現・置換テキスト(URL、Match、Replace全て)
url は置換テキスト扱い。http://host/path/の様な完全な物か、/から始まる絶対パス以外は使用出来ない(../〜等の相対パスは\uに置き換えられてしまう)
Proxomitronに接続して来たものに、Location:ヘッダを返して、指定したURLに移動させようとする。
(通常一般的なブラウザは、Location:ヘッダを受け取った場合、自動でそのURLに新しく接続する=別の接続になる)
↓実際に返すヘッダ HTTP/1.1 302 Redirect Content-Length: 0 Connection: close Location: url
※Inで使用し、元々のサイトが発見出来なかった場合は、エラー画面が出て、移動しない。
※http://localhost/ だと、Outでのみ有効になる。
hostsファイルを弄って、localhostt等に変更してみると、Inも有効。
また、localhost:80の様にポートを付けるとInも有効になることから、localhost/〜の場合だけInが無効になる様子。
IE6の場合、$JUMP(file://C:/a.txt) の様に file:// を使うとローカルのファイルを直接参照可能(この場合、ブラウザがキャッシュしない為高速)
使用可能な場所 : [HTTP Headers]の検索表現・置換テキスト(URL、Match、Replace全て)
url は置換テキスト扱い。http://host/path/の様な完全な物以外は使用出来ない(../〜等の相対パスは\uに置き換えられてしまい、絶対パスはエラーになる)
指定したURLに移動する。 ReDIRect
$RDIRで移動後、再度$RDIRを使用して他のアドレスに移動しようとしても、それは処理されない。
※Inで使用し、元々のサイトが発見出来なかった場合は、エラー画面が出て、移動しない。
※http://localhost/ だと、Outでのみ有効になる。
hostsファイルを弄って、localhostt等に変更してみると、Inも有効。
また、localhost:80の様にポートを付けるとInも有効になることから、localhost/〜の場合だけInが無効になる様子。
$RDIR(file://C:/a.txt) の様に file:// を使ってもローカルのファイルは参照不能 URLコマンドのfile//を使うしかない(この場合ブラウザにキャッシュされる)
4.5beta から追加された機能
(バグ) 最長一致として働く状態の * の後ろに$SET()コマンドを使うと正常に機能しない。
例えば以下のケースでは [合致なし] になってしまう。
Bounds = "<img*>" Match = "*$SET(\0=success)" Replace = "[\0]" Text = "<img test-string>"
対処法としては * と $SET() の位置を入れ替えると期待通りに動くことが多い。
Match = "$SET(\0=success)*"
↓↓↓
[Patterns] Name = "TEST: *$SET(0=!)" Limit = 256 Match = "*$SET(0=!)" Replace = "[\0]" Text = "abc" Result = "[!]a[!]b[!]c"
つまり、「Match = "*$SET(\0=success)"」の * は最短一致として動作し、空にマッチしているため、[合致なし] になっているだけで、紛らわしいが、バグとは言えない。
他に
・ フィルターはマッチしているのに代入されない
・ 最長一致として働くはずの * が最短一致になり空文字にマッチする
などの不具合を確認しています。
4.5beta から追加された機能
Match で取り込んだ変数を同じ Match で使いたいなどという場合、以下のような表現になる。(重複単語の削除)
Match = "\s(\w+{1,*})\0\s$TST(\0)(^(^\s))"
Replace = "\0"
(バグ) 『 $SET(\0=abc)$TST(\0) 』などの "$SET + $TST + ローカル変数" の
組合わせは機能せず "[合致なし]" になる。
テスト用文字列 = "hogehoge"
・ "$SET + $TST + ローカル変数"
$SET(\0=hogehoge)$TST(\0) → "[合致なし]"
・ "$SET + $TST + グローバル変数"
$SET(N=hogehoge)$TST(N) → マッチ
・ "()\0 + $TST + ローカル変数"
(hoge)\0$TST(\0) → マッチ
・ "()\0 + $SET + $TST + ローカル変数"
(hoge)\0$SET(\0=hoge)$TST(\0) → "[合致なし]"
・ "$SET + ()\0 + $TST + ローカル変数"
$SET(\0=hoge)(hoge)\0$TST(\0) → マッチ
※ (hoge)\0 で代入し直しているのでマッチする。
使用可能な場所 : 検索表現・置換テキスト
matching valueは検索表現扱い。前方一致。
プロトコルを含んだURLのチェック。
$URL(yahoo.co.jp/) × マッチする事はありえない $URL(http://yahoo.co.jp/) 〇 $URL([^/]+//yahoo.co.jp/) 〇
使用可能な場所 : Incoming Header FilterとPatternsの検索表現・置換テキスト
header-name はリクエストヘッダ名完全一致
(大文字小文字は問わず)。コマンド等使用不可
matching は検索表現扱い。前方一致。
リクエストヘッダの値のチェック。
WEBフィルタで利用する場合、ヘッダフィルタで置換された後のヘッダが 出力される。 ヘッダフィルタでどうなるかは未検証。 $IHDRも同じ。
使用可能な場所 : Patternsの検索表現・置換テキスト
header-name はリプライヘッダ名完全一致
(大文字小文字は問わず)。コマンド等使用不可
matching は検索表現扱い。前方一致。
リプライヘッダの値のチェック。
OUT中に$IHDRを使用した場合、当然空 とも限らない
→ out 時に $IHDR を使用する = $OHDR と間違えたんだろうということで、Proxomitron が $OHDR として処理する $OHDR でも空だった場合は、空を返す (4.3, 4.4, 4.5m, 4.5j, 4.5j338, 4.5j+6 で確認)
以下例 http://abc.s65.xrea.com/tools/filtertest/nph-test.cgi で試してください
[HTTP headers] In = TRUE Out = TRUE Key = "URL: test $ALERT($[OI]HDR(Content-Type: ))" URL = "abc.s65.xrea.com/tools/filtertest/" Match = "($OHDR(Content-Type: \0)|)($IHDR(Content-Type: \1)|)" Replace = "$ALERT(out = \0\r\nin = \1)"
ヘッダフィルタの「URL のマッチ (URL)」は、リクエスト(out)時に一度だけ処理される。
そのため、$IHDR を、ヘッダフィルタの「URL のマッチ (URL)」で使った場合、値が取得できないか、$OHDR の値になる。
以下例 test2, test3 は動作するが、test1 は動作しない(http://abc.s65.xrea.com/ で試してください)
[HTTP headers] In = TRUE Out = TRUE Key = "URL: test1 $IHDR(Server: \0)" URL = "abc.s65.xrea.com/(^?)$IHDR(Server: (^Proxomitron)\0)$ALERT(test1 Server: \0)" In = TRUE Out = TRUE Key = "URL: test2 $IHDR(Server: \0)" Match = "http://abc.s65.xrea.com/(^?)$IHDR(Server: (^Proxomitron)\0)$ALERT(test2 Server: \0)" [Patterns] Name = "test3 $IHDR(Server: \0)" Active = TRUE URL = "abc.s65.xrea.com/(^?)$IHDR(Server: (^Proxomitron)\0)$ALERT(test3 Server: \0)" Limit = 256 Match = "<start>"
使用可能な場所 : Incoming Header FilterとPatternsの検索表現・置換テキスト
matching は検索表現扱い。前方一致。
ステータスコード(「200 OK」「404 Not Found」など)のチェック。
使用可能な場所 : Patternsの検索表現
code は htm / css / js / vbs / oth のいずれかの文字に限られる。(大文字小文字は問わず)
Content-Typeのチェック。$IHDR(Content-Type:)で代用することも可能。
例えば、$TYPE(css) は、4.3, 4.4 では $IHDR(Content-Type: text/css*) のように、本来あるべき値(text/css)の最後に「*」を付けた物に一致するが、4.5m, 4.5j では 「text/cs*」の様に最後の一文字を削った物に一致する($TYPE(vbs)なら、「text/vbscrip*」)。4.5のバグと思われる。 4.5では$IHDR(Content-Type:)を使用した方が良いかも知れない。
※4.5June338 や 4.5June+6, 4.5June+7 は、4.3, 4.4 よりも正確になっている。
使用可能な場所 : 検索表現・置換テキスト
keycode list は[0-9a-z]もしくは「^」で始まる独自のキー名か仮想キーコード。大文字小文字は区別しない。
指定したキーが押されていたかどうかを判定し、押されていたらマッチする。2つ以上のキーを指定することも可能。
0〜9、A〜Zはそのまま書いてよい。
$KEYCHK(g) Gキー $KEYCHK(12) 1キー+2キー (ただしテンキーでは無効)
特別に用意されたキー名。
$KEYCHK(^c) Ctrlキー $KEYCHK(^a) Altキー $KEYCHK(^s) Shiftキー $KEYCHK(^t) TABキー $KEYCHK(^f1) F1キー (f2〜f12も同様)
その他の特殊キー・記号キー・テンキー・マウスボタン等は10進数の仮想キーコードを用いる。
$KEYCHK(^13) Enterキー $KEYCHK(^192) [@]キー $KEYCHK(^97) テンキーの[1] $KEYCHK(^1^2^4) マウスの左ボタン+右ボタン+中ボタン
仮想キーコードは、一覧表を検索するか以下のようなスクリプトで調べよう。
<script>//IE用
(d=document).onkeydown=d.onmousedown=function(){
d.body.innerHTML+="<br>$KEYCHK(^"+(event.keyCode||event.button)+")";
return false;}
</script>
アドレスバーに以下を入力して実行でもOK
javascript:(d=document).onkeydown=d.onmousedown=function(){d.body.innerHTML+="<br>$KEYCHK(^"+(event.keyCode||event.button)+")";return%20false;};eval()
使用可能な場所 : 置換テキスト
textは置換テキスト扱いではなく、変数使用不可
text内の一部の文字を、Proxomitronが動作しているPCの時間に書き換える。
「$DTM(Y/M/D H:m:s)」は、「2006/4/3 23:23:31」の様になる。
$SET(hour=$DTM(H)) の様に、変数に代入すれば$TSTを使用して検索表現にも使用可能
| パラメータ | 2001年02月03日 04時05分06秒 GMT+9 の例 | 説明 |
|---|---|---|
| 年 | ||
| Y | 2001 | 西暦年4桁 Year |
| 月 | ||
| M | 2 | 月1桁 1 から 12 Month |
| 日 | ||
| D | 3 | 日1桁 1 から 31 Day |
| 曜日 | ||
| w | Sat | 英語曜日(3文字の省略文字型) Mon から Sun ※4.5以降のみ day of the week |
| 時 | ||
| h | 04 | 時間2桁 01 から 12(AM0時でもPM0時でも12) hour ※4.3ではAM0時は00、PM0時は12を返す |
| H | 04 | 時間2桁 00 から 23 Hour |
| 分 | ||
| m | 05 | 分2桁 00 から 59 minute |
| 秒 | ||
| s | 06 | 秒2桁 00 から 59 second |
| 全ての日付/時刻 | ||
| d | 2001-2-3 | 西暦年4桁-月1桁-日1桁 = Y-M-D date |
| E | 3/2/2001 | 日1桁/月1桁/西暦年4桁 = D/M/Y EU |
| I | Fri, 02 Feb 2001 19:05:06 GMT | 英語曜日, 日2桁 英語月 西暦年4桁 時間2桁:分2桁:秒2桁 GMT ※グリニッジ標準時(日本時間はGMTに9時間足したもの) RFC 822, updated by RFC 1123 Internet Format |
| T | 04:05:06 | 時間2桁:分2桁:秒2桁 = H:m:s Time |
| U | 2/3/2001 | 月1桁/日1桁/西暦年4桁 = M/D/Y US |
| その他 | ||
| t | 858 | ミリ秒(1/1000秒) 00 から 999 thousand |
| c | 23 | 現在の接続番号 1 から 無限? connection |
| a | am | 午前ならamを、午後ならpmを返す am/pmのa |
| p | am | 午前ならamを、午後ならpmを返す am/pmのp |
月2桁、日2桁は無い
使用可能な場所 : 置換テキスト
filenameにはコマンド等使用不可
filenameで指定された任意のローカルファイルを読み込み、その内容を返す。
$FILE(C:\\temp\\aaa.txt) $FILE(C:/temp/bbb.css) $FILE(html\\ccc.js)
フォルダの区切りは \\ か / を使う必要がある。 ドライブ名を省略するとproxomitron.exeのあるフォルダを表す。 \d や http:// で始まるパスは使えない。日本語を含むパスの場合、2byte目が \ ( 0x5C ) である文字はエスケープしなければならない。このコマンドは呼ばれるごとにファイルを読みに行く(メモリに蓄積はされない)ので、ファイルの更新はすぐに反映される。
このコマンドを用いてフィルタエディタだけでは実現できない置換が可能となる。 例えばUTF-16LEのページにおいて 0x00 を含む文字列をReplaceしたい場合に、フィルタエディタからは困難である。ところが、Replaceしたい内容をあるテキストファイルにUTF-16LEで保存*1 しておき、
Replace = "$FILE(html\\UTF16LE.txt)"
などとしておけば比較的容易である。
使用可能な場所 : [Patterns]のMatch
Content-Type: text/html* か multipart/x-mixed-replace* の場合のみ有効(4.5の場合、text/htm* か multipart/x-mixed-replac*)
ヘッダ、フッタにJavascriptを埋め込む時などに使用する。
本文直前か、本文終了直前の1回のみに反応するので、$STOP()は不要
Matching Expressionに、<start> または <end> 以外の何かを入れると、<start>、<end>が通常の文字として処理されるようになる。「a|<start>」「a|<end>」「$URL(\0)<start>」「$URL(\0)<end>」の様な物も無効。
<start>または<end>が有効である場合は、そのフィルタにおけるBoundsとLimitの値は無視される。よって、変数・コマンド・条件分岐等は「URL」を使う必要がある。
URL = "$URL(\0)($IHDR(Last-Modified:\1)|)" Match = "<start>" Replace = "<!-- \0 \1 -->"
<start>で大量の文字列をページ先頭に挿入すると、IEの文字コード自動判別が上手く動作しなくなる事がある。それを回避するには例えば以下のように書き換える。
URL = "$TYPE(htm)" Match = "(^(^<(script|/head|body)))$STOP()" Replace = "<挿入文>"
<start>でなんらかの文字列をページ先頭に挿入すると、IE6のDOCTYPEスイッチが無効になるので、回避する場合は以下のように書き換える。
URL = "$TYPE(htm)" Limit = 256 Match = " (<!DOCTYPE*>|)\0$STOP()" Replace = "\0<挿入文>"
<start>、<end>を使ったフィルタを複数入れる場合でも Multi = "true" は不要。
マッチする順番は普通のフィルタと同じで上から順にマッチしていく。
<end>は他のフィルタが \k で読み込みを中止した場合でも働く。
この場合、置換テキストの出力は \kフィルタ → <end>フィルタ の順となる。
http://www.pluto.dti.ne.jp/~tengu/proxomitron/help/URL_Commands.html
|