3

これらの正規表現は私を殺しています。何を読んでも概念を理解できません。

これが私の問題であり、解決するのは非常に簡単だと確信しています。

[img:http://example.com/_data/025_img.jpg]

私が望むのは、 [img: ... ] というビットを<img>タグで変更し、次のように結果を取得することだけです

<img src='http://example.com/_data/025_img.jpg' border='0' />

私はあらゆる種類のばかげたバリエーションを試しましたが、うまくいきませんでした。私はそれについて驚いていません。

編集

追加情報:

私の状況は次のとおりです。

  1. ユーザーが自分のプロフィールに画像をアップロードする

  2. イメージ名は db に保存されます。

  3. それらは、テキストエリアを持つフォームの横にリストされています
  4. テキストを入力しているときに、次のタグ [img: ... ] を追加して、1 つ以上の画像を含めるようにユーザーに提供したいと思います。ここで ... は、リストされている画像をクリックするとコピーされるリンクです。ユーザーギャラリーから。
  5. 私はCodeigniterを使用しており、ビューを介してテキストエリアをコントローラーに渡しています->モデルでは、あらゆる種類のヘルパーによってサニタイズされます... sql/quotesなど..XSSはCIでも有効になっています

  6. 次に、テキストをスキャンして、ユーザーが [img: ... ] タグを持っている場所を確認し、それをタグに交換して、<img>画像とそれに続くテキストで投稿をレンダリングしたいと思います。

したがって、ユーザーからの実際の入力は、次のようなものになります。

The brown fox jumped over foo bar [img:http://example.com/_data/025_img.jpg] and then went to bed [img:http://example.com/_data/0277_img.jpg] while thinking about [img:http://example.com/_data/1115_img.jpg]

これが、preg_match ではなく preg_replace を要求した理由です。preg_match はテキストを画像に追従させません。

4

4 に答える 4

4

まず、簡単なことを邪魔にならないようにしましょう。

/\[img:([^\]]+)\]/

あれは:

  • リテラル[img:
  • を含むキャプチャグループ
    • で構成される文字クラス
      • 文字通りではないもの]
    • 少なくとも1回繰り返す
  • リテラル]

これを実行すると、一致配列の要素1は、タグpreg_matchに簡単に挿入できる画像URLになる可能性が非常に高くなります。img

しかし、あなたはすべきではありません。すぐではありません。

まず、これは一体として安全ではありません。これを書くとどうなりますか?

[img:javascript:alert(document.cookie);]

ええとああ。それは良くないでしょう。

おそらく、ユーザーがURLであると主張するものが実際にURLであることを確認したいと思うでしょう。を呼び出すことでこれを試すことができますparse_url。それはあなたにURLコンポーネントの配列を返します。モノにドメインとパスがあり、HTTPまたはHTTPSで提供されていることを確認してください。

わかりましたが、ユーザーがこれを入力するとどうなりますか?

[img:http://www.example.com/foo.jpg" onmouseover="alert(document.cookie)"]

これは有効な...ish... URLであり、によって正常に分解されparse_url、整形式の基本的なチェックに合格する可能性があります。スペースと引用符(シングルダブル)を除外することは良い出発点になりますが、まだ心配することがあります。

肝心なのは、このようなマークアップはXSSのベクトル、またはクロスサイトスクリプティングの脆弱性であるということです。

URLをに渡すことで、脅威の一部を軽減できる可能htmlspecialcharsがあります。それは少なくとも引用符と括弧を無効にするでしょう、そして世話をする人たちに厄介になるのは難しいです。文字セットの愚かさに注意してください。UTF-8以外の文字エンコードの中には、ASCII引用符であるものを含めることができるものがあります...

これにはおそらく実際のマークアップ言語を使用したいと思うでしょう(たとえそれが単なるマークダウンであっても)、そしておそらく結果にHTMLPurifierのようなホワイトリストベースのHTMLフィルターを使用したいと思うでしょう。これは、あるレベルの狂気からあなたを守るのに役立ちます。

彼らがあなたを捕まえるために出ていない場合にのみ、あなたはパラノイアであることを忘れないでください。ウェブは、彼らが悪意を持っているほど愚かである人々と、それが愚かであるほど悪意を持っている人々でいっぱいです。

于 2012-12-09T09:46:18.297 に答える
2

正規表現が気に入らない場合は、使用する必要はありません。少なくともこの目的のためではありません。

次のようにする必要があります。

$in = "[img:http://example.com/_data/025_img.jpg]";

if (strpos($in, "[img:") === 0)
{
    $in = "<img src='" . substr($in, 5, -1) . "' border='0' />";
}

echo $in;

ただし、これは正規表現の方法になります。

$in = "[img:http://example.com/_data/025_img.jpg]";

preg_match("~\[img\:(.*?)\]~", $in, $matches);

if ($matches)
{
    echo "<img src='" . $matches[1] . "' border='0' />";
}

簡単な説明:

パターンは次のとおりです。"~\[img\:(.*?)\]~"

~パターンの区切りとして使用します。開始[文字は正規表現であるため、エスケープする必要があります。imgそのままにしておくことができますが、:再びエスケープする必要があります。その後、任意の文字が続くことができます: .*- クエスチョン マークは、選択を「貪欲でない」にすることです。の出力としてマークされるように (中かっこ) で囲みます$matches。その後、]もう一度閉じます-それだけです。

更新:Gumbos のコメントを参照してください:。エスケープする必要はありません。

于 2012-12-09T09:39:25.350 に答える
1

正規表現は難しいですが、強力です。私はグルではないので、それが最善の解決策であるとは思いません。

$regEx = '/\[img:http:\/\/[\w]{3,10}\.(com|org|us){1}[\w\/]{5,15}\.(jpg|png|gif){1}\]/i';

$string = 'someting before [img:http://example.com/_data/025_img.png], something after [img:http://example.org/_data/025_img.jpg] and end of the line EOL';
$pstring = $string;
$matches[0] = array();
preg_match_all($regEx, $string, $matches);

一致する配列は次のようになります。

Array
(
    [0] => Array
        (
            [0] => [img:http://example.com/_data/025_img.png]
            [1] => [img:http://example.org/_data/025_img.jpg]
        )

    [1] => Array
        (
            [0] => com
            [1] => org
        )

    [2] => Array
        (
            [0] => png
            [1] => jpg
        )

)

さて、ここで何が起こっているのですか:

  1. 正規表現

/-正規表現
\[img:http:\/\/を開始 - すべての文字列は次の文字列で始まる必要があります[img:http://
[\w]{3,10}- 3 ~ 10 個の数字、文字、アンダースコアのみの行で、ドメイン名になると予想されます (ただし、ドメインにアンダースコアが含まれている必要があるかどうかはわかりませんが、最適化の良い点です)
\.-ドット
(com|org|us){1}- これらの人の 1 つ
[\w\/]{5,15}- パスとして 5 行から 15 行まで、私が含めたことに注意してください / ここに加えて
\.- ドット
(jpg|png|gif){1}- これらの人の 1 つ
\]- パターンの終わり -
/i大文字と小文字を区別しないようにします

  1. preg_match_allは、指定された文字列内のすべての一致を検索します。追加の部分文字列は、枝から角かっこに の 2 番目と 3 番目の要素として一致します。$matches理由はほとんどわかりません。そのため、誰かがこれを理解するのに役立つ場合は、それを理解していただければ幸いです。

  2. 次に、単純な文字列操作を使用して、すべての前菜を置き換えることができます

このようなもの: (if最初に空の $matches[0] を追加したため、ステートメントがないことに注意してくださいifs:))

foreach ($matches[0] as $match) {
    $img = str_replace(array('[img:',']'), array('<img src="', '" />'), $match);
    $pstring = str_replace($match, $img, $pstring);
}

必要に応じて、正規表現をいじったり、単純にしたり、より複雑にしたりできます。

$pstring出力は

someting before <img src="http://example.com/_data/025_img.png" />, something after <img src="http://example.org/_data/025_img.jpg" /> and end of the line EOL

ここに遊び場がありますhttp://phpfiddle.org/main/code/bbu-e24

于 2012-12-10T00:43:26.280 に答える
0
<?php
$str = '[img:http://example.com/_data/025_img.jpg]';
$image = '<img src="'.str_replace(array("[img:","]"),"",$str).'" border="0">';
echo $image;?>
于 2012-12-09T09:42:51.993 に答える