【问题标题】:match subdomain for a redirect匹配重定向的子域
【发布时间】:2013-04-28 05:47:04
【问题描述】:

我想匹配 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 尝试了一些东西,但它并没有真正奏效。

【问题讨论】:

    标签: php regex redirect preg-match


    【解决方案1】:

    你可以试试这个模式:

    ~^((?:\w+\.)*?)subdomain\.example\.com~
    

    如果您允许这个.toto.subdomain.example.com,只需在开头添加\.?

    ~^((?:\.?\w+\.)*?)subdomain\.example\.com~
    

    如果您想允许连字符,只需将其添加到字符类中:

    ~^((?:\.?[\w-]+\.)*?)subdomain\.example\.com~
    

    如果您不允许子字符串以连字符开头或结尾:

    ~^((?:\.?\w+([\w-]*?\w)?\.)*?)subdomain\.example\.com~
    

    【讨论】:

    • 感谢这完美的作品!只有一件事关于带有“连字符”的子域(te-st.example.com)?见:regexr.com?34ose
    猜你喜欢
    • 1970-01-01
    • 2018-04-04
    • 2020-09-27
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2021-11-18
    相关资源
    最近更新 更多