PHP如何将模式转换为正则表达式?

PHP如何将模式转换为正则表达式?,php,regex,preg-match,preg-match-all,Php,Regex,Preg Match,Preg Match All,如何使模式成为正则表达式 首先,我将此:id作为我的url模式之一,我想将其转换为正则表达式,以便它可以匹配1或2或3 $requestUrl = 'foo/1/'; $regex = 'foo/:id/'; $match = preg_match($regex, $requestUrl); 因此,$match应该是true 我有这个 $route = 'foo/:id/'; var_dump((preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*

如何使模式成为正则表达式

首先,我将此
:id
作为我的url模式之一,我想将其转换为正则表达式,以便它可以匹配
1
2
3

$requestUrl = 'foo/1/';
$regex = 'foo/:id/';

$match = preg_match($regex, $requestUrl);
因此,
$match
应该是
true

我有这个

$route = 'foo/:id/';
var_dump((preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)));

但是我得到的结果是
int0

为什么这么复杂?正则表达式应该相当简单,如下所示:

foo/[0-9]+/
如果您希望更精确,并且仅当该字符串中没有其他内容时才匹配,则必须为线端开始和结束添加锚定:

^foo/[0-9]+/$
请注意,这只是普通的正则表达式,如果要将其提供给函数
preg_match()
,则必须执行一些额外的步骤,因为该函数是如何工作的:

preg_match('/^foo\/[0-9]+\/$/', $requestUrl)
开始编写自己的正则表达式的一个好主意是使用许多在线正则表达式测试工具之一。它们允许你一步一步地发展你的表情。如果您在使用函数文档时遇到问题,一定要查看它:

关于自动将模式转换为正则表达式:一般来说,这不容易回答。就你的例子而言,据我所知,方法可能是这样的:

$requestUrl = 'foo/1/';
$requestPattern = 'foo/:id/';

preg_match('/^(.*\/):id(\/.*)$/', $requestPattern, $tokens);
define('DELIM', '/');
$requestRegex = sprintf(DELIM.'^%s[0-9]+%s$'.DELIM, 
                        preg_quote($tokens[1], DELIM), 
                        preg_quote($tokens[2], DELIM));

echo preg_match($requestRegex, $requestUrl) ? 'true' : 'false';
说明:第一次,准备调用
preg_match()
时,您将从占位符
:id
旁边的模式中提取这些部分。然后,您可以在下面对
sprintf()
的调用中使用这些部分来构造正则表达式。需要调用
preg_quote()
,才能将零件中出现的任何
/
字符解释为所创建正则表达式中的分隔符。为了便于理解,我引入了常量
DELIM
,这里仅作为示例设置为
/


显然,解决方案取决于模式的性质,我只能通过您给出的单个示例来猜测…

我建议以下几点:

  • 正则表达式模式的每一端都需要有分隔符(我已经使用了
  • 如果您想获取数字,请使用
    ()
  • 使用诸如
    \d
    或字符类
    [0-9]

    (对于多个数字,使用
    +
    (匹配一个或多个数字)或
    *
    (零或多个)

  • 下面是一个正在使用的示例:

    $regex = "!foo\/(\d)\/!";
    $requestUrl = "foo/1/";
    
    $result = preg_match($regex, $requestUrl);
    
    要练习和完善正则表达式,请尝试以下在线工具之一:


    谢谢,但是我在您的建议中发现了这个错误
    警告:preg_match():在C:\…
    中找不到结尾分隔符“^”你能把我的答案读到结尾吗?这看起来像是你在函数调用中尝试了第二个版本。显然这不起作用。我在我的答案中这么说。aww明白了。谢谢。但是我如何将
    'foo/:id/'
    转换为
    '/^foo\/[0-9]+\/$/“
    ?嗯,这不是一般可以回答的问题。只有当你有“典型模式”时,这个问题才有意义使用变量,以便可以声明传输规则。现在唯一清楚的是一个字符串,其中包含一个数字部分。这就是正则表达式已经处理的内容。让我这样问:为什么不能简单地使用上面所示的正则表达式的字面形式?好的,我尝试了一下,检查修改后的答案:-)