【问题标题】:Create string from regular expression PHP从正则表达式 PHP 创建字符串
【发布时间】:2011-10-27 14:04:29
【问题描述】:

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

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

现在我想说“应用程序”等于“a”,“控制器”等于“b”,“方法”等于“c”,“参数”等于“d”。然后我应该得到一个字符串,用指定的值替换部分。不过,我找不到这样做的好方法。我基本上想到了两种方法:1)用指定的值替换正则表达式中的相应值,或者 2)创建一个自定义的“正则表达式语法”,您可以轻松地使用它来创建字符串并将其转换为“适当的" 需要时的正则表达式。 Kohana 使用后者,但两种方式对我来说听起来都很糟糕。你会怎么做呢?

编辑:我会尝试澄清一下。例如,我使用preg_match() 将以下字符串传递给上面显示的正则表达式:“myApplication/myController/myMethod/myParameters”。这将返回一个包含几个项目的数组,其中包括 4 个项目,其索引为“应用程序”、“控制器”、“方法”和“参数”以及相应的值。现在我必须使用正则表达式的模式创建字符串“myApplication/myController/myMethod/myParameters”,而我只有包含 4 个项目的数组。如何使用 PHP 做到这一点?

【问题讨论】:

  • 这个不清楚。你能举一个输入字符串和相应输出字符串的例子吗?
  • 我对 php 和正则表达式非常熟悉,但是我不知道你在问什么。你的问题对我来说零意义,我建议你从头开始编辑你的问题。但谁知道呢,也许别人明白。
  • @Oli Charlesworth, Gerry:我知道这可能很难理解,我自己解释时遇到了麻烦……我添加了一些文字,希望现在更清楚。
  • @Frog:你的问题现在只是稍微清楚了一点。一般规则是“xyz”->“myXyz”吗?
  • 感谢@Oli Charlesworth 的回复!不,这不是我真正的意思。我必须创建一个与正则表达式中的模式相对应的字符串,并将数组中的值填充到命名组中。我基本上必须做相反的操作:我已经有了正则表达式和值,现在我必须在正则表达式中填写值,所以我得到一个字符串,当传递给 preg_match() 时,正则表达式返回相同价值观。我自己解释了吗?

标签: php regex url


【解决方案1】:

考虑到preg_match 支持命名捕获组(当然,您的正则表达式正在使用;more here),这应该非常简单。

一个例子from PHP documentation

<?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?&lt;(\w+)&gt;\)/ 替换为那里的捕获组的值。

但是由于 PHP 并没有真正让您在替换期间只使用捕获组的值来访问变量,因此您可能必须分多个步骤来执行此操作……例如匹配上述组的所有出现,提取命名组,然后最后(在$matches 作为$match 的循环中)从'(?P&lt;' . $match . '&gt;)''(?&lt;' . $match . '&gt;)'$$match 的值的简单字符串替换(虽然比那更安全)。

【讨论】:

  • 感谢您的回答!我明白这一点,这正是我现在正在做的事情。我正在尝试做的是反转此操作:我知道(在您的示例中)“名称”是什么以及“数字”是什么,现在我想使用我知道的值创建一个与正则表达式模式相对应的字符串.例如,我知道“name”等于“test”,“digit”等于“2000”,然后我的函数应该创建一个字符串“test: 2000”。
  • 感谢您的回答@Alan H.!这正是我的意思,你的例子真的很有帮助。所以你认为使用正则表达式的子集是最好的方法吗?它不会大大减慢页面速度吗?
  • 嗯,每次浏览量你会做多少次这样的事情?少数几次应该是相对无关紧要的。
  • 抱歉回复晚了。我确定昨天我检查时您的答案没有出现在这里..?无论如何,它可能不会在每个页面视图上发生超过 3 次。我目前正在创建自己的子集,实际上进展顺利。 :)
猜你喜欢
  • 1970-01-01
  • 2016-01-13
  • 2018-07-15
  • 1970-01-01
  • 2021-07-19
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多