1

私はphpBB3を使ってメッセージボードを作っています。投稿内のすべての URL を取得してリンクとしてレンダリングする機能が組み込まれています。ローカル リンクのみがクリック可能になるようにしたいと考えています。

phpbb3 は投稿のテキストに正規表現を使用し、一致するたびにそれをリンクに変更します。

if ($somestuff){
// matches a xxxx://aaaaa.bbb.cccc. ...
$magic_url_match[] = '#(^|[\n\t (>.])(' . "[a-z]$scheme*:/{2}(?:(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#ie';
$magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')";

// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
$magic_url_match[] = '#(^|[\n\t (>])(' . "www\.(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#ie';
$magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')";
}
return preg_replace($magic_url_match, $magic_url_replace, $text);

これらの正規表現を書き直して、自分のドメインのリンクのみに一致するようにするにはどうすればよいですか? さらに、正規表現を独学するための最良の方法は何ですか?

4

1 に答える 1

2

これは最初のもので、セクションごとに分割されています。これを行うことでさえ、取るに足らないことではありませんでした...

(
    ^
|
    [\n\t (>.]
)

OK、ここでは単に「行の先頭、または改行、タブ、スペース、より大きい、期間の後にあります。正規表現を固定するだけです。

(
    [a-z]$scheme*:/{2}

これはまさにここでの純粋な狂気です。$schemeおそらく保持しますhttp。これは、この正規表現がに一致することを意味しhttp://ます。なぜ誰かが/{2}の代わりに使うのか//、私は推測し始めることができません。

    (?:
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@|]+
        |
            %[\dA-F]{2}
        )+
    |

これは一連の文字、おそらくURLで有効な文字と一致します。注目すべきは、$inlinePHP変数(それが何を保持しているのか推測できない)と、2番目の選択肢である%[\dA-F]{2}。これ%20は、スペースなど%に一致します。それ以外の場合、一致(またはURL)での記号は合法ではありません。

ここでも重要なのは、それ/が合法ではないということです。したがって、これはディレクトリを参照することはできず、ドメインのみを参照します。これは、Webサイトの適切なドメインに単純に一致させるために、変更したい部分である可能性があります。

ただし、完全を期すために、残りはここにあります。

        [0-9.]+
    |

または、一連の数字とピリオド(IPアドレス)を使用することもできます。この正規表現がどれほど複雑かを考えると、彼が行かなかったことに驚いてい(?:\d{1,3}\.){3}\d{1,3}ます...

        \[
        [a-z0-9.]+
        :
        [a-z0-9.]+
        :
        [a-z0-9.:]+
        \]
    )

これが最後の選択肢です。これはIPv6用だと思います。とにかく、これはコロンで区切られた一連の16進数です。これらは角かっこで囲まれている必要がありますが、特にタグに非常に多く使用するフォーラムソフトウェアの場合は、奇妙だと思います...

    (?:
        :
        \d*
    )?

ここでは、コロンに続くいくつかの数字のオプションがあります。つまり、これはポートが含まれているURL用です。

    (?:
        /
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@|]+
        |
            %[\dA-F]{2}
        )*
    )*

さて、最初に示したように、ここでサブディレクトリに到達しました/。それ以外の場合、これは同じ「正当なURL文字」の一致です。

    (?:
        \?
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@/?|]+
        |
            %[\dA-F]{2}
        )*
    )?
    (?:
        \#
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@/?|]+
        |
            %[\dA-F]{2}
        )*
    )?
)

最後に、によって渡されるものGET(で示される\?)、およびページ中央のアンカーにリンクするURL(で示される)\#

結論:

このセクション:

    [a-z]$scheme*:/{2}
    (?:
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@|]+
        |
            %[\dA-F]{2}
        )+
    |
        [0-9.]+
    |
        \[
        [a-z0-9.]+
        :
        [a-z0-9.]+
        :
        [a-z0-9.:]+
        \]
    )

次のようなものに置き換える必要があります。

    [a-z]$scheme*://
    www\.example\.com

または多分

    [a-z]$scheme*://
    (?:
        www\.example\.com
    |
        192\.168\.0\.1
    |
        ::ffff:192\.168\.0\.1
    )

ドメインとIPアドレスがWebサイトと一致する場所。明らかに、私が行った改行とインデントを削除する必要があります。私はあなたのためにそれをしますが、あなたがあなたのドメインをそのすべての真ん中に置く場所を見つけるのに苦労するので、それはほとんど価値がないと思います。

おそらく、サブドメインや、またはあなたが持っているものを除外している人々のために、いくつかの正規表現を含めることをお勧めしwww.ます。

これを削除することもできます:

    (?:
        :
        \d*
    )?

あなたはおそらく人々があなたのドメインの他のポートにリンクすることを望まないでしょう。

2つ目は、ほぼ同じ構造になっているように見えます。コメントが言うように、それはプロトコル指定子を欠いているURLを取得しているだけです。

于 2012-08-17T03:43:28.747 に答える