【问题标题】:Parsing string - with regex or something similar?解析字符串 - 使用正则表达式或类似的东西?
【发布时间】:2012-01-26 10:01:58
【问题描述】:

我正在编写路由类,需要帮助。我需要解析 $controller 变量并将该字符串的一部分分配给另一个变量。下面是 $controller 的例子:

$controller = "admin/package/AdminClass::display"
//$path = "admin/package";
//$class = "AdminClass";
//$method = "display";

$controller = "AdminClass::display";
//$path = "";
//$class = "AdminClass";
//$method = "display";

$controller = "display"
//$path = "";
//$class = "";
//$method = "display";

这三种情况就是我所需要的。是的,我可以编写很长的程序来处理这种情况,但我需要的是使用正则表达式的简单解决方案,带有函数 preg_match_all

有什么建议吗?

【问题讨论】:

  • 关于其他解析情况/您可能需要解析的其他字符串,请在您的问题中更加具体。第一个到第二个值可以通过替换/子字符串/拆分来完成。
  • 为什么需要使用正则表达式?
  • @CanSpice,匹配这三种情况,然后将部分字符串提取到变量中

标签: php regex text-parsing


【解决方案1】:

以下正则表达式应该为您完成此操作,然后您可以将捕获的组保存到 $path$class$method

(?:(.+)/)?(?:(.+)::)?(.+)

这是一个Rubular: http://www.rubular.com/r/1vPIhwPUub

您的 php 代码可能如下所示:

$regex = '/(?:(.+)\/)?(?:(.+)::)?(.+)/';
preg_match($regex, $controller, $matches);
$path = $matches[1];
$class = $matches[2];
$method = $matches[3];

【讨论】:

  • 谢谢!如果您有任何可以让我轻松学习正则表达式的链接,我将不胜感激:)
  • 我使用regular-expressions.info/reference.html 作为备忘单,该网站有一些很好的教程。 Rubular 对于快速测试您的正则表达式也非常有用。
  • 这也将匹配a/b,这是不合法的输入!
【解决方案2】:

这假设类中的路径和方法名只能包含字母。

完整的正则表达式如下:

^(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+)$

两个非捕获组:第一个使所有路径和类都是可选的,第二个避免捕获单个路径元素。

解释:

  • 路径元素是一个或多个字母后跟 /:[a-zA-Z]+/;
  • 可能有零个或多个:我们必须在上面应用*量词;但是正则表达式不是原子,因此我们需要一个组。由于我们不想捕获单个路径元素,因此我们使用非捕获组:(?:[a-zA-Z]+/)*;
  • 如果完整路径存在,我们要捕获完整路径,我们必须在此 ((?:[a-zA-Z]+/)*) 上使用捕获组;
  • 方法名是一个或多个字母,我们要捕获它:([a-zA-Z]+);
  • 如果存在,则跟随路径,后跟两个分号:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::;
  • 但所有这些都是可选的:因此我们必须围绕所有这些设置一个组,这也是我们不想捕获的:(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?;
  • 最后,后面是一个方法名,这次不是可选的,我们要捕获它:(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+);
  • 我们希望它匹配整行:我们需要在开头和结尾都锚定它,这给出了最终结果:^(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+)$

呼。

【讨论】:

  • 第二个正则表达式返回类,方法是 AdminClass::display。我认为 F.J. 的正则表达式可以用作第二个
  • 嗯,它确实可以用一个正则表达式来完成,而且没有错误,但它会是一个很长的正则表达式,需要更多的解释;)如果你愿意,我可以把它做起来并解释一切。
  • 这不也匹配a/b并将其全部放入$method吗?
  • 是的,这就是为什么我建议用更严格的正则表达式替换.*。但请参阅编辑。
  • 完成。现在有了完整的比萨:p
【解决方案3】:
        $pieces = explode('/',$controller); 
        $path = '';
        for($i = $i<$pieces.length-1; $i++)
        {
          if($i != 0)
             $path+='/';
          $path += $pieces[$i];
        }
        $p2 = explode(  '::',$pieces[$pieces.length-1]);
        $class = $p2[0];
        $method = $p2[1];

【讨论】:

    猜你喜欢
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多