使用PHP从正则表达式创建字符串

3

我正在尝试从一个正则表达式创建一个字符串。我注意到在Kohana框架的路由系统中,您可以使用类似于正则表达式的东西设置路由。然后,您可以创建匹配您设置的路由的URL。我正在尝试做类似的事情,但我找不到一个干净的方法来做到这一点。例如,我有以下正则表达式:

/^(?<application>\w+)\/(?<controller>\w+)\/(?<method>\w+)\/(?<parameters>\w+)\/?$/

现在我想要能够说“应用程序”等于“a”,“控制器”等于“b”,“方法”等于“c”和“参数”等于“d”。然后,我应该得到一个字符串,将指定值替换为部分。但是我找不到一个好的方法来完成这个任务。我基本上考虑了两种方法:1)使用指定的值替换正则表达式中的对应值,或2)创建一个自定义“正则表达式语法”,可以轻松地使用它来创建字符串,并在需要时将其转换为“合适的”正则表达式。Kohana使用后者,但我认为这两种方法都不太好。您会如何做到这一点?
编辑:我将尝试澄清一下。例如,我使用preg_match()将以下字符串传递给上述正则表达式:“myApplication / myController / myMethod / myParameters”。这将返回一个数组,其中包含一些项,包括4个带有索引“application”,“controller”,“method”和“parameters”的项目,以及相应的值。现在,当我只有那个包含4个项目的数组时,如何使用正则表达式的模式创建字符串“myApplication/myController/myMethod/myParameters”?我应该如何使用PHP实现这一点?

1
这不是很清楚。你能否举个例子,展示一个输入字符串和相应的输出字符串? - Oliver Charlesworth
我非常熟悉PHP和正则表达式,但是对于你的问题我一点儿头绪都没有。你的问题对我来说完全没有意义,建议你重新从零开始编辑问题。不过谁知道呢,也许有其他人能理解。 - Gerry
@Oli Charlesworth,Gerry:我知道这可能很难理解,我自己也有解释困难的问题...我添加了一些文本,希望现在更清晰了。 - Frog
1
@Frog:你的问题现在只是稍微清晰了一点。一般规则是“xyz”->“myXyz”吗? - Oliver Charlesworth
感谢@Oli Charlesworth的回复!不,那不是我想表达的。我必须创建一个字符串,对应于正则表达式中的模式,并使用命名组中填充的值。我基本上要执行反向操作:我有正则表达式和值,现在我必须在正则表达式中填入这些值,以便得到一个字符串,当将其传递给带有该正则表达式的preg_match()时返回相同的值。我解释清楚了吗? - Frog
@Gerry:请看下面Alan的回答,我相信他理解我的意思,也许那可以帮助你理解。 - Frog
1个回答

2

鉴于 preg_match 支持命名捕获组(显然,你的正则表达式正在使用;有关更多信息,请参见此处),因此这应该是相当简单的。

下面是 PHP 文档中的一个示例

<?php

$str = 'foobar: 2008';

preg_match('/(?P<name>\w+): (?P<digit>\d+)/', $str, $matches);

/* This also works in PHP 5.2.2 (PCRE 7.0) and later, however 
 * the above form is recommended for backwards compatibility */
// preg_match('/(?<name>\w+): (?<digit>\d+)/', $str, $matches);

print_r($matches);

?>

上述示例将输出:
Array
(
    [0] => foobar: 2008
    [name] => foobar
    [1] => foobar
    [digit] => 2008
    [2] => 2008
)

在您的情况下,您可以使用您的$matches数组,例如$matches['application']


编辑:好吧,我没有完全理解这个问题。

使用正则表达式生成字符串的一个明显问题是,正则表达式可以匹配无限字符串。例如,/cat\s+rat/匹配所有以下内容:

cat rat
cat  rat
cat   rat

但在您的示例中,没有任何未定义的内容。

因此,您倾向于定义一个“安全”的或单一可生成的语言,它是正则表达式的子集,在狭窄的用例下是一个好选择。然后,您可以将 /\(\?P?<(\w+)>\)/ 的出现替换为其中捕获组的值。

但由于PHP实际上不允许您仅使用捕获组的值在一个步骤中访问变量进行替换,因此您可能需要分多个步骤来完成此操作...例如,匹配上述组的所有出现次数,提取命名组,最后在循环 $matches 作为 $match 进行简单的字符串替换,从 '(?P<' . $match . '>)''(?<' . $match . '>)'$$match 的值(虽然以更安全的方式)。


谢谢你的回答!我明白了,这正是我现在正在做的。不过我现在想要做的是反向操作:我知道(在你的例子中)“name”和“digit”的含义,现在我想创建一个字符串,该字符串对应于使用我所知道的值的正则表达式模式。例如,我知道“name”等于“test”,“digit”等于“2000”,那么我的函数应该创建一个字符串“test: 2000”。 - Frog
谢谢你的回答,@Alan H!这正是我想表达的,你的例子非常有帮助。那么你认为使用正则表达式的子集是最好的方法吗?它不会显著减慢页面速度吗? - Frog
好的,每页您会执行多少次这样的操作?执行几次应该相对不太重要。 - Alan H.
抱歉回复晚了。昨天我检查时,你的答案可能没有显示在这里?无论如何,每个页面视图上可能不会发生超过3次。我目前正在创建自己的子集,进展还不错。 :) - Frog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接