【问题标题】:Match a .htaccess content with regular expression in PHP将 .htaccess 内容与 PHP 中的正则表达式匹配
【发布时间】:2014-02-14 05:17:57
【问题描述】:

我正在尝试 regex 匹配 .htaccess 文件内容中的几件事。

基本上所有 cmets之间 ##bbc-startSOME_IP_HERE_AND_SOME_LABEL##bbc-end

想法是抓取cmets之间的规则,如果存在的话,用空字符串替换:

<IfModule mod_rewrite.c>
RewriteEngine On
##bbc-start-1Mail.RU_Bot
RewriteCond %{REMOTE_HOST} -1 [OR]
RewriteCond %{HTTP_USER_AGENT} Mail.RU_Bot 
RewriteRule . - [F]
##bbc-end
##bbc-start66.249.78.150googlebot
RewriteCond %{REMOTE_HOST} 66.249.78.150 [OR]
RewriteCond %{HTTP_USER_AGENT} googlebot 
RewriteRule . - [F]
##bbc-end
##bbc-start157.55.33.50bingbot
RewriteCond %{REMOTE_HOST} 157.55.33.50 [OR]
RewriteCond %{HTTP_USER_AGENT} bingbot 
RewriteRule . - [F]
##bbc-end
</IfModule>

使用的模式是:

$regex_pattern = "/##bbc-start{$bot_banned_ip}{$bot_banned_mark}(.*?)##bbc-end/m"; 

...{$bot_banned_ip}{$bot_banned_mark} 在运行时提供。

上面的模式已经过测试并且在http://www.rubular.com/r/bfoeQnah49在线上运行良好

http://www.regexe.com/ 上,但令人惊讶的是无法在PHP 环境中工作,5.3.18 与preg_match()preg_replace()

我错过了什么,是我的环境有问题吗?

编辑:确切的代码是:

$file_contents = '<IfModule mod_rewrite.c>
    RewriteEngine On
    ##bbc-start-1Mail.RU_Bot
    RewriteCond %{REMOTE_HOST} -1 [OR]
    RewriteCond %{HTTP_USER_AGENT} Mail.RU_Bot 
    RewriteRule . - [F]
    ##bbc-end
    ##bbc-start66.249.78.150googlebot
    RewriteCond %{REMOTE_HOST} 66.249.78.150 [OR]
    RewriteCond %{HTTP_USER_AGENT} googlebot 
    RewriteRule . - [F]
    ##bbc-end
    ##bbc-start157.55.33.50bingbot
    RewriteCond %{REMOTE_HOST} 157.55.33.50 [OR]
    RewriteCond %{HTTP_USER_AGENT} bingbot 
    RewriteRule . - [F]
    ##bbc-end
    </IfModule>';
$regex_pattern = "/##bbc-start{$bot_banned_ip}{$bot_banned_mark}(.*?)##bbc-end/m";
$match = preg_match($regex_pattern, $file_contents);
//preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.    
if ($match===1) { /*DO SOME STUFF*/}

奇怪的是$match总是0。

【问题讨论】:

    标签: php regex .htaccess preg-match


    【解决方案1】:

    我相信您需要 s 开关 DOTALL 和 preg_quote 函数来为可能的正则表达式符号转义变量。

    试试这个正则表达式:

    $regex_pattern = "/##bbc-start" . preg_quote($bot_banned_ip, '/') . 
                     preg_quote($bot_banned_mark, '/') . "(.*?)##bbc-end/is";
    

    还要检查你的正则表达式:

    var_dump ( $regex_pattern );
    

    【讨论】:

    • 使用 preg_quote() 的模式是 /##bbc\-start127\.0\.0\.1opera(\.*\?)##bbc\-end/s
    • 但是我在你的 .htaccess 中没有看到任何歌剧文本
    • 是的,这只是一个例子(opera或IP是动态的),您修改的模式是/##bbc-start127\.0\.0\.1opera(.*?) ##bbc-end/是
    • 谢谢,preg_quote() 是这里的关键,必须使用它。
    • 不客气。是的,确实没有preg_quote,只要变量中有/,代码就会中断。
    【解决方案2】:

    You want to use the s modifier, not ms 用于 DOTALL,它允许 . 匹配换行符。

    【讨论】:

    • 它让我发疯,整天都在放松,确切的代码在问题中,没什么特别的,我有 .htaccess 文件中的内容,我搜索上述案例
    • 您确定在读取文件时换行符(行尾)与输入多行源时相同吗?无论如何,'s' 修饰符 应该 将换行符视为空白字符,将数据视为一个长字符串。当然,$bot_banned_ip 和 $bot_banned_mark 是定义的,具有合理的值?
    • 是的,所有值都是合理的,它们直接来自.htaccess,我很高兴你为我指出了使用“s”修饰符的方向,问题是值应该用preg_quote(),正如 anubhava 建议的那样。
    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    相关资源
    最近更新 更多