3

私は多言語サイトに取り組んでおり、言語ごとにカスタム URL を使用することも選択しました。たとえば、次のようになります。

/en/cities/paris/
/nl/steden/paris/

どちらも Cities コントローラーの Index メソッドを指しています。

すべてのページに言語を切り替えるオプションがあり、ルートを調べてコントローラー、ビュー、言語を一致させます。

したがって、オランダ語のページにいる場合、英語版の適切な URL が見つかります。これは「steden」ではなく「cities」になります。

より複雑な正規表現を使い始めるまでは、すべてうまくいきました。

目的の URL に一致する次の正規表現があります。

#^en/cities/([^/]+?)/$#
#^nl/steden/([^/]+?)/$#

私のコードでは、一致する変数 (この例では「paris」) にアクセスできます。この正規表現を「反転」して、「en/cities/paris/」と出力することは可能でしょうか?

そうでない場合.. URLが異なることを考慮して、どうすれば同じページの異なるバージョンへのリンクを作成できますか..できれば可能な限りプログラムできるようにしてください。

やや似た質問で、誰かが答えました (http://stackoverflow.com/a/7070734/616398) 正規表現の本質は無限の数の結果に一致することです..それは不可能かもしれません.

文字列/URL から一致する基準のセットに移行して MVC で使用するのは非常に簡単ですが、その逆は..残念ながらそれほど多くはありません。

4

1 に答える 1

1

はい、可能です!この場合、次のソリューションをコーディングしました。

$regex = '#^en/cities/([^/]+?)/$#';
$replace = array('paris');

$result = preg_replace_callback('#^\^|\([^)]*\)|\$$#', function($m)use($replace){
    static $index = 0;
    if($m[0] === '^' || $m[0] === '$'){return '';}
    if(isset($replace[$index])){
        return $replace[$index++];
    }
    return $m[0];
}, substr($regex, 1, -1));
echo $result; // en/cities/paris/

オンラインデモ

「柔軟」にしたので、より多くの値を追加できます。

$regex = '#^en/cities/([^/]+?)/region/([^/]+?)$#'; // <<< changed
$replace = array('paris', 'nord'); // <<< changed

$result = preg_replace_callback('#^\^|\([^)]*\)|\$$#', function($m)use($replace){
    static $index = 0;
    if($m[0] === '^' || $m[0] === '$'){return '';}
    if(isset($replace[$index])){
        return $replace[$index++];
    }
    return $m[0];
}, substr($regex, 1, -1));
echo $result; // en/cities/paris/region/nord

オンラインデモ


説明:

$regex = '#^en/cities/([^/]+?)/region/([^/]+?)$#'; // Regex to "reverse"
$replace = array('paris', 'nord'); // Values to "inject"

/*  Regex explanation:
   #   Start delimiter
       ^\^         Match "^" at the begin (we want to get ride of this)
       |           Or
       \([^)]*\)   Match "(", anything zero or more times until ")" is found, ")"
       |           Or
       \$$         Match "$" at the end (we want to get ride of this)
   #   End delimiter
*/

$result = preg_replace_callback('#^\^|\([^)]*\)|\$$#', function($m)use($replace){
    static $index = 0; // Set index 0, note that this variable is only accessible in this (anonymous) function
    if($m[0] === '^' || $m[0] === '$'){return '';} // Get ride of ^/$ at the begin and the end
    if(isset($replace[$index])){ // Always check if it exists, for example if there were not enough values in $replace, this will prevent an error ...
        return $replace[$index++]; // Return the injected value, at the same time increment $index by 1
    }
    return $m[0]; // In case there isn't enough values, this will return ([^/]+?) in this case, you may want to remove it to not include it in the output
}, substr($regex, 1, -1)); // substr($regex, 1, -1) => Get ride of the delimiters
echo $result; // output o_o

:これはPHP 5.3+でのみ機能します

于 2013-05-17T23:46:53.243 に答える