我正在使用多语言网站,并选择使用每种语言的自定义网址,例如:
/en/cities/paris/
/nl/steden/paris/
两者都指向Cities控制器的Index方法。
在每个页面上都有一个切换语言的选项,它会在我的路线中查找控制器,视图和语言。
因此,如果我在荷兰语页面上,它会找到英文版的正确网址,即“城市”而不是“steden”。
一切正常,直到我开始使用更复杂的正则表达式。
我有这些正则表达式符合我想要的网址:
#^en/cities/([^/]+?)/$#
#^nl/steden/([^/]+?)/$#
在我的代码中,我可以访问正在匹配的变量,在此示例中为“paris”。是否可以“反转”这个正则表达式并打印'en / cities / paris /'
如果没有..考虑到URL是不同的,我将如何获得指向同一页面的不同版本的链接...最好将其尽可能地编程。
在一个有点类似的问题中,有人回答(http://stackoverflow.com/a/7070734/616398)正则表达式的本质是为了匹配无数个结果..所以它可能是不可能的。
很容易从字符串/ URL转到一组匹配的标准,以便在MVC中使用,但另一种方式......不用说,不幸的是。
答案 0 :(得分: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/
<强> Online demo 强>
我已将其设为“灵活”,因此您可以为其添加更多值!
$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
<强> Online demo 强>
<强>解释强>
$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 +