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


PHP how to turn a pattern into a regex?

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

出于意图,我将这个:id作为我的 url 模式之一,我想将其转换为正则表达式,以便它可以匹配123

$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)));

但结果我得到了int 0

我有几点建议:

  1. 正则表达式模式需要在两端都有分隔符(我已经用过!
  2. 如果要专门抓取数字,请使用( )创建捕获组
  3. 使用元字符(如 'd)或字符类[0-9]简化模式

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

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

$regex = "!foo'/('d)'/!";
$requestUrl = "foo/1/";
$result = preg_match($regex, $requestUrl);

要练习和完善您的正则表达式,请尝试以下在线工具之一:

https://regex101.com/r/sB3bH9/1

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

foo/[0-9]+/

如果你想更精确,并且只在该字符串中没有其他内容时才匹配,那么你必须为行尾开始和结束添加锚点:

^foo/[0-9]+/$

请注意,这只是普通正则表达式,如果您想将其馈送到函数preg_match(),那么由于该函数的工作方式,您必须采取一些额外的步骤:

preg_match('/^foo'/[0-9]+'/$/', $requestUrl)

开始编写自己的正则表达式的一个好主意是使用众多在线正则表达式测试工具之一。它们允许逐步开发您的表情。如果您在使用函数文档时遇到问题,查看它当然总是一个好主意:http://php.net/manual/en/function.preg-match.php

关于自动将模式转换为正则表达式:这通常不容易回答。对于您的示例,据我了解,该方法可能是这样的:

$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仅作为示例设置在此处/

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