タグ別アーカイブ: regular expression

スパムに効く正規表現5-Shift_JISひらがな判定と文字数カウント

掲示板 CGI で英文スパムを弾くのに、ひらがなが含まれているかをチェックすることがあるでしょう。例えば、掲示板スパム対策 – 日本語がないメッセージの書き込みを禁止する では、コメントに Shift_JIS ひらがな、カタカナが含まれているかを判定するために、次の様な Perl の正規表が紹介されています。

if ($in{'comment'} !~ /(x82[x9F-xF2])|(x83[x40-x96])/) {
	&error("日本語を書いてください。");
}

このコードは例えば b、c という文字列を見逃してしまいます。何故ならこの文字列には x82 xa4 という、ひらがなの「う」を表すコードの並びが入っているからです。

    b      、       c
x82 x82  xa4  x82 x83

この場合は次のように、2文字連続するパターンを正規表現で表現すれば誤判定の頻度はグッと減るでしょう。

if ($in{'comment'} !~ /(x82[x9F-xF2])|(x83[x40-x96]){2}/) {
	&error("日本語を書いてください。");
}

しかし敵も然る者、一部に簡単な日本語を混ぜて投稿をしてきます。こうなると日本語の文字数と英数字の文字数を数え、一定以上日本語が含まれているかどうかをチェックしたくなります。今回はそんなエントリーです。

2010年10月1日追記

ロシア人の という意味のロシア語 Русское が2回続くパターンがあることが分かりました。

    Р         у         с         с         к         о         е
x84 x51  x84 x85  x84 x83  x84 x83  x84 x7b  x84 x80  x84 x75

ロシア語には сс を含む単語が結構あるので、上記正規表現の {2}{3} に変えるか、こういう対処療法がイヤな人は次章を参照してください。
続きを読む

スパムに効く正規表現4-Shift_JIS以外の文字を削除する

かなり前のことですが、掲示板 CGI (Shift_JIS で書かれた Perl スクリプト)のスパムフィルターにかかった投稿を管理画面で開いた際、レイアウトが崩れたことがありました。UTF-8 で投稿された記事をスクリプト側が処理できず、Shift_JIS で表示をしようとしたブラウザが タグの開始記号 < を解釈出来なかったのでは?、と当時その原因を推定しました。日本語環境から普通に投稿すれば、こちらの指定した charset で返してくるのがまっとうなブラウザの動作だと思うので、かなり怪しい投稿と言えます。

さて、タグが乗っ取られないように対策することにしたのですが、当時私の使っていた @nifty は一切の Perl 用モジュールが使えず、UTF-8 を処理できない jcode.pl を使用せざるを得ませんでした(Jcode.pm を個別にアップロードするという手はありましたが…)。そこで表題のような正規表現を考えたわけです。

現在では CGI が動作するホスティングサービスであれば encode モジュールが普通に使えるので、もはやニーズのないエントリーなのかもしれませんが、G アサーションを使った正規表現の応用と考えれば、誰かの役に立つかもしれないと思いポストします。
続きを読む

スパムに効く正規表現3-文字化けしないShift JIS空白の削除

掲示板 CGI には大抵、禁止ワードを含んだ投稿をスパム扱いする機能が備わっていますが、例えば「きんし」という単語に対し、敵は「き ん し」などとスペースを入れて投稿してきたりします。当然、CGI 側は次のような正規表現と s/// 演算子を使って記事中の空白・改行(x81x40 は Shift JIS で全角スペースを表します)を削除した後、投稿禁止ワードを検索したりするわけです。

$text =~ s/s|x81x40|<br>//ig;

一方 Perl は $text の中身が Shift JIS か UTF-8 かなどはお構い無しに、単にバイトデータ列としてマッチングと置換を行いますので、上記の Perl コードでは例えば a@Ab` に変わってしまうなど、文字化けが発生してしまいます。

勿論、人目に触れることのない処理なので影響はないのですが、今回は Shift JIS の文字列を正しく区切りながらマッチングを行う正規表現について考えてみたいと思います。
続きを読む

スパムに効く正規表現2-URLの分解とドメイン名の抽出

ウチのCGI掲示板には、スパムと判定された投稿からURLのドメイン名を抽出し、投稿禁止ワードとして一定期間保持する機能を持たせています。他のスパム判定フィルタと合わせることでモレを少なくする効果を狙ったものですが、特にスパム対策が未熟だった頃、この機能に引っかかったスパム投稿も少なくありませんでした。

さて、正規表現 URL 分解 を Google で検索する と第1位に「正規表現サンプル(URLを分解する)」が挙がり、次のような正規表現が紹介されています。

^(.+?)://(.+?):?(d+)?(/.*)?$

この正規表現は、左側のカッコから順に スキームホストポートパス へと分解してくれるのですが、http://127.0.0.1/ の様にIPアドレスで構成されたURLの場合、ホストが 127.0.0.、ポートが 1 となってしまうという問題点があります。

もちろんこれを改善する正規表現を作ることは出来るのですが、ここでは RFC2396日本語訳) に従ってURIを分解する正規表現を検証してみたいと思います。
続きを読む

スパムに効く正規表現1-aタグのURLを正しく自動リンクする

KENT WEByy-board などのCGI掲示板には大抵、書き込まれたURLを自動リンクする機能が備わっていますが、

<a href="http://example.com/">http://example.com/</a>

の様にaタグ付きで書き込まれた場合、次の様にURLの区切り位置を誤ってリンクが張られる事があります。

<a href="http://example.com/">http://example.com/</a>

今回は掲示板へのスパム書き込み自体を防止するネタではありませんが (タイトルがビミョー ;-))、このうっとおしい状況を改善する正規表現について書いてみます。
続きを読む