![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
No.12ベストアンサー
- 回答日時:
タグを許可する時は「全てのタグをエスケープし、許可するもののみ戻す」という方法をとります。
以下、入力文字列が $val に入っているものとします。
タグのエスケープでは、
$val =~ s/&/&/g;
$val =~ s/</</g;
$val =~ s/>/>/g;
$val =~ s/"/"/g;
を行います。( & の変換は最初に行うこと)
属性のないタグは
$val =~ s/<(\/?b)>/<$1>/gi;
という方法で元に戻します。
多くの掲示板でそうであるように、特殊な入力を強いる必要はありません。
(許可するタグの「閉じタグ」もこの方法で戻します。)
属性のあるタグは、タグを解析します。
正規表現で許可するタグを拾い、それぞれのタグ解析ルーチンから正常な属性文字列を取得してタグを戻します。
# ↓ここに許可するタグを書く
while ($val =~ /<(font|img)\s+(.*?)>/gi) {
my $tgt = quotemeta $&; # 拾ったタグ全体
my ($tag, $attr) = ($1, $2);
$attr =~ s/"/"/; # 属性部をアンエスケープ
$attr =~ s/&/&/;
my @attrs = split /\s+/, $attr; # 属性を分解
# それぞれのタグ解析ルーチンへ
if ($1 =~ /font/i) { $tag .= tag_font(@attrs); }
elsif ($1 =~ /img/i) { $tag .= tag_img(@attrs); }
# タグを戻す
$val =~ s/$tgt/<$tag>/;
}
例えば font タグ用の解析ルーチン tag_font は、次のようになります。
sub tag_font {
my $tag;
foreach (@_) {
my ($attr, $val) = split /=/;
$val =~ tr/"'//d;
# 許可する属性のみ $tag に追加する
if (lc($attr) eq 'size') {
# ±1~3 または 1~7 を許可
if ($val =~ /^[+-][1-3]|[1-7]$/) {
$tag .= qq{ $attr="$val"};
}
}
elsif (lc($attr) eq 'color') {
if ($val =~ /^#[A-Fa-f0-9]{6}|[A-Za-z]+$/) {
$tag .= qq{ $attr="$val"};
}
}
}
return $tag;
}
また、URLやメールアドレスの自動リンクについては、「Perlメモ(参考URL)」というサイトの「http URL の正規表現」や「メールアドレスの正規表現」の項にある正規表現が大変便利です。
各項の一番最後に書かれている $http_URL_regex と $mail_regex を使い、次のように書くことができます。
・メールアドレスの自動リンク
$val =~ s/($mail_regex)/<a href="mailto:$1">$1<\/a>/g;
・URLの自動リンク
URLの自動リンクには注意が必要です。
なぜなら $http_URL_regex が、imgタグのsrc属性値までも対象としてしまうからです。
これを回避するためには、次のように書きます。
while ($val =~ /($http_URL_regex)/g) {
my $url = $1;
# マッチした URL の後続文字列 $' の先頭を調べ、
# img の src や変換済み URL を変換しないようにする
if ($' !~ /^"|<\/a>/) {
$val =~ s/$url/<a href="$url">$url<\/a>/;
}
}
以上を組み合わせれば、タグの許可および自動リンクが実現できます。
参考URL:http://www.din.or.jp/~ohzaki/perl.htm
No.13
- 回答日時:
> 多くの掲示板でそうであるように、特殊な入力を強いる必要はありません。
どちらも一長一短ありますね。
(タグを多用することがあるかどうかは)掲示板のテーマしだいですが、タグ(の書き方)を記述するのに、「<div>」、「<b>」等と使い分けなきゃいけないのもどうかと思いますけど。すべて文字参照、というのはもっといやですね。
特殊な入力とはいっても、工夫さえすれば問題ないと思いますよ。
これも、#6で紹介したphpBBで採られていた方法をいただいたのですが、マウスクリックまたはメタキーでサイクリックに入力できるので、直接書くよりは楽です。
あとは、質問者さんの好みで決めればいいのではないでしょうか。
No.11
- 回答日時:
またまたすみませんです。
補足を意味を取り違えておりました。> <a hreh>はhttpで始まるものは自動でリンクに変換(よく見かけますよね)のほうが良いのでは?この方法はどうしたらいいでしょうか?
いいかどうかはポリシー、ページのテーマにもよると思います。
例えばここですが、解説のために例示した架空のURLがリンクになっては困りますよね。
個人的には明示的に入力する方を選びます。
やり方は #6,#10および#10のURLを参考にガンバッテください。
No.10
- 回答日時:
> <a hreh>はhttpで始まるものは自動でリンクに変換(よく見かけますよね)のほうが良いのでは?この方法はどうしたらいいでしょうか?
> あとの問題は、<font>と<img>。<>内に語句が入るため> |**|では対応できないですよね。何か良い方法無いでしょうか?
#6に回答が書いてありますよ?
あれを、perlに書き換えるだけです。perlの場合、「/」をエスケープする必要があるかも分かりません。
<a href=\"\\1\" target=\"_brank\">\\1</a>
の\\1が、正規表現に一致した内容、つまり、|url|,|/ulr|ではさまれたURLになります。
\\1の数字の部分が、「(」の出現順の番号です。\\2なら、httpかftpですね。
> htm(l)で終わる分は<a href></a>に変え[HOME]等を表示
気休めですが、[HOME]のような表示はやめて、URLをそのまま表示した方が、良いかと思います。
<img>は#6の正規表現をアレンジして最後に 「\.(gif|jpg|jpeg|png|)」を追加すればいいかな。
正規表現については、参考URLの「perl」に詳しい解説が有ります。
参考URL:http://tohoho.wakusei.ne.jp/www.htm
No.9
- 回答日時:
補足です。
タグですが、入力を簡単にするため、許可したタグのボタンを全部ならべて、クリックでテキストエリアに入力するJavaScriptを組んであります。これなら、何が使用可能か一目瞭然です。
ところで、画像は具体的にどうしたいのでしょうね?
自由度が増すほど登録メンバーのみ投稿を許可などの制限を設けた方が良いと思います。
phpBBという高機能な掲示板がありまして、サーバ側で用意して選択させる方法、サイズを制限してアップロード可能な方法、画像へのリンク、いずれも出来るようになっており参考になりました。もちろんメンバー制です。
ソースはかなり複雑です。
#6のサンプルは、英数字、チルダ、ハイフン、スラッシュ、ドット以外の文字が含まれていたら変換しないようになってます。
(イメージは拡張子 gif, jpg, pngのみ許可。)
> ただ、<A>や<IMG>許可するようであれば、
> タグ全て許可と対して変わらないかもしれませんよ。
表示の問題もあるのでなるべく制限した方がいいでしょう。<table>など下手に使われると目茶苦茶になりますしね。
No.8
- 回答日時:
たぶん、皆さんの発言で解決は出来ると思いますが、
質問するのでしたら、テキストエリア内でタグを利用できるように・・・
ではなく、
掲示板の投稿時、タグを反映させたいのですが・・・
でしたね。
タグの全て許可はたしかに危険ですが、
JavaScriptと、スタイルシートの許可さえしなければ、
いうほど危険もないかもしれません。
ただ、<A>や<IMG>許可するようであれば、
タグ全て許可と対して変わらないかもしれませんよ。
conconなんてのがあるし、<A>内にJavaScriptでなんでもありになりますから。
文字装飾だけの許可にしては?
URLのリンクは、#4さんがおっしゃるような形か、
URL部分を抜いておいて( 参照リンク )と言った形でリンクするとかね。
最後に、タグ閉じ忘れのケアレスミスにご注意を。
この回答への補足
回答ありがとうございます。
なにぶん初心者なので、どう説明したら良いのかがわからず、変な書き方しちゃいました。すみませんでした。
さて、問題の件ですが、リンクは#7でも書きましたが、自動変換で対応できないかと考えました。これでもダメですか?
<img>はやっぱり必要なんです。どうにかならないですかね…
…
……
でも、よく考えると、<img>使用するんだったら画像アップローダーが必要ですよね。
ただの画像表示(リンクのみ)だったらさっきの自動リンクで何とかならないですかね。
htm(l)で終わる分は<a href></a>に変え[HOME]等を表示、gif・jp(e)gは<img>に変換…
こんな都合いい事出来ないですか?
No.7
- 回答日時:
#6 です。
すいません、また、違ってました。ポストしたあと見たら書いたほど、厳密なチェックではありませんね。
やろうとしたのですが、
http://xxxx.yyy.zz/~abc/ddd.eee/index.html
なんてのまで考えると複雑になりすぎるので断念したのでした。
この回答への補足
いろいろとありがとうございます。
いろいろと弊害があるということがわかってきたので、ちょっとやり方を変えたいと思います。
<B>は「$value =~ s/|b|/<b>/g; 」で対応するとします。
<a hreh>はhttpで始まるものは自動でリンクに変換(よく見かけますよね)のほうが良いのでは?この方法はどうしたらいいでしょうか?
あとの問題は、<font>と<img>。<>内に語句が入るため|**|では対応できないですよね。何か良い方法無いでしょうか?
No.6
- 回答日時:
> $value =~ s/</</g;
> $value =~ s/>/>/g;
> $value =~ s/|b|/<b>/g;
> であってますか?
それで OKです。
ついでに、URLのやり方ですが、|url|http://~|/url|の形で入力して
$str = ereg_replace("|url|((http|ftp)://(([0-9a-zA-Z\-~_]+)\.)+([0-9a-zA-Z\-~_]+)([0-9a-zA-Z\-~_\./]*))|/url|","<a href=\"\\1\" target=\"_brank\">\\1</a>",$str);
とやってます。
PHPなので、perlとは違いますが、正規表現は使えるのではないでしょうか。
上記の正規表現は、URLの記述の正しさのチェックもおこなっています。
○ http://xxxx.yyyy.zzz
× http://xxx.yyy.zzz.
× http://xxx.yyy
という結果になるはずです。
# もっと簡単に書けるかもわかりませんが、//以下が必ず三つ以上のパートから構成されていて最後が2文字以上の英字でないとNG(変換されずにそのまま表示される)になるように厳密にチェックしています(..のつもりなんですが)。
いい加減に評価するならもっと簡単になります。
No.5
- 回答日時:
#4です。
一箇所間違えました。>修正機能をもたせる場合、<は&lt;と変換してテキストエリアに表示しないとタグが有効になってしまいます。
「<を&lt;と変換しないと、< と表示されず < になる」に訂正します。
No.4
- 回答日時:
最近、限定タグのみ使用可能にした掲示板を完成させたばかりなので。
「テキストエリア」とは #1に書いてある通り、掲示板等で入力するためのエリア(質問をポストした時のあの入力するための領域のことです)なのでタグの効果は反映されません。
スタイルシートで色や文字の大きさを指定したりする程度のことが出来るのは#2の通りです。
で、私の場合、
1.<, >を<, >に変換してタグを無効化。
2.特別に決めた表現のみHTMLタグに変換。例えば、|b|等と表現した場合に<b>に変換。
というふうにやりました。
但し、URLなど、値が変わる場合、正規表現を使う必要がありますし、入力された文字の正当性を評価することも必要だと思います(URLが複数指定された場合を考慮すると、かなり複雑な正規表現になります)。
修正機能をもたせる場合、<は&lt;と変換してテキストエリアに表示しないとタグが有効になってしまいます。
全てのタグを許可するなら、なにもしなくてもOKですが、やめといた方が無難だと思います。
ありがとうございます。そのことが知りたかったんです。
sub Decode内に「$value =~ s/</</g;」と「$value =~ s/>/>/g;」があったためコメントアウト「先頭に#」してタグが有効になるようにしました。
ただ、言われるとおりこのままだとすべてのタグが使用できてしまうんですよね。
<a href><B><font><img>のみ使用可能というCGIを見かけましたが、どうやっているのですか?DLして中を見てみたのですが、いまいちよくわからずです。
ちなみに、
>例えば、|b|等と表現した場合に<b>に変換。
は、
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/|b|/<b>/g;
であってますか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで集計したい。
-
apacheでPerl CGIが作動せず、5...
-
CGI内でけいたいスマホの振り分け
-
サーバーのエラーでおしえてく...
-
フォームを再送信しますか?
-
/bin/awk '{print $5}'ってどう...
-
フォームメールを受信すると文...
-
.htaccessについて
-
ホームページでCGIのフォームを...
-
めちゃきれい
-
number 改行が追加できない
-
生成AI画像について
-
3DCG
-
ホームページにメールフォーム...
-
cgi アクセス制限 エラー
-
CGIの記述について教えてくださ...
-
CGIの設置が分かりません・・・
-
ホームページにCGIを設置したの...
-
ホームページにCGIを設置したの...
-
ホームページの事でおしえてく...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで集計したい。
-
フォームを再送信しますか?
-
apacheでPerl CGIが作動せず、5...
-
ホームページでCGIのフォームを...
-
/bin/awk '{print $5}'ってどう...
-
ラズパイでのCGIで、pythonソー...
-
CGIって何ですか?簡潔に教えて...
-
(フリーの)ツリー掲示版CGI、...
-
入力フォーム(電話番号)
-
CGI.pmはもう古い!?
-
サイト訪問者の情報を取得したい
-
htmlからパラメータで、cgiに渡...
-
チェックボックスでのvalue値の...
-
POSTメソッドの最大容量について
-
cgiのパスについて
-
古ーくからフリーのtree.cgi掲...
-
-T(汚染モード)でメールが送れ...
-
CGI経由PDFダウンロードでエラー
-
フォームメールを受信すると文...
-
めちゃきれい
おすすめ情報