我想匹配PHP变量$_SERVER['SERVER_NAME']
中的子域,然后执行内部重定向。 Apache或nginx重写不是一个选项,因为这是客户端/用户可见的外部重写。
我的正则表达式为(.*(?<!^.))subdomain\.example\.com
,因为您可以看到我匹配子域(多级子域)中的子域。我希望稍后使用第一个捕获组。
这是我的PHP代码:
if(preg_match('#(.*(?<!^.))subdomain\.example\.com#', $_SERVER['SERVER_NAME'], $match1)) {
echo $match1[1] . 'anothersubdomain.example.com';
}
但如果子域名为csssubdomain.example.com
,则会失败,因为这是另一个我不想匹配的子域。使用以下PHP脚本,我测试匹配:
$tests = array(
'subdomain.example.com' => 'anothersubdomain.example.com',
'css.subdomain.example.com' => 'css.anothersubdomain.example.com',
'csssubdomain.example.com' => 'csssubdomain.example.com',
'tsubdomain.example.com' => 'tsubdomain.example.com',
'multi.sub.subdomain.example.com' => 'multi.sub.anothersubdomain.example.com',
'.subdomain.example.com' => '.subdomain.example.com',
);
foreach( $tests as $test => $correct_answer) {
$result = preg_replace( '#(.*(?<!^.))subdomain\.example\.com#', '$1anothersubdomain.example.com', $test);
echo 'Input: ' . $test . "\n" .
'Expected: ' . $correct_answer . "\n" .
'Actual : ' .$result . "\n";
$passorfail = (strcmp( $result, $correct_answer) === 0 ? "PASS\n\n" : "FAIL\n\n");
echo $passorfail;
}
你会得到as output:
Input: subdomain.example.com
Expected: anothersubdomain.example.com
Actual : anothersubdomain.example.com
PASS
Input: css.subdomain.example.com
Expected: css.anothersubdomain.example.com
Actual : css.anothersubdomain.example.com
PASS
Input: csssubdomain.example.com
Expected: csssubdomain.example.com
Actual : cssanothersubdomain.example.com
FAIL
Input: tsubdomain.example.com
Expected: tsubdomain.example.com
Actual : tsubdomain.example.com
PASS
Input: multi.sub.subdomain.example.com
Expected: multi.sub.anothersubdomain.example.com
Actual : multi.sub.anothersubdomain.example.com
PASS
Input: .subdomain.example.com
Expected: .subdomain.example.com
Actual : .subdomain.example.com
PASS
奇怪的是,它确实匹配csssubdomain.example.com
但不匹配tsubdomain.example.com
。
有人知道你可以用于这种情况的正则表达式吗?我用lookahead and lookbehind zero-width assertions尝试过一些东西,但它确实没用。
答案 0 :(得分:1)
你可以尝试这种模式:
~^((?:\w+\.)*?)subdomain\.example\.com~
如果您允许此.toto.subdomain.example.com
,只需在开头添加\.?
:
~^((?:\.?\w+\.)*?)subdomain\.example\.com~
如果你想允许连字符,只需将它添加到字符类:
~^((?:\.?[\w-]+\.)*?)subdomain\.example\.com~
如果您不允许子字符串以超级字符开头或结尾:
~^((?:\.?\w+([\w-]*?\w)?\.)*?)subdomain\.example\.com~