preg_match()返回最长的匹配

时间:2014-10-14 22:04:42

标签: php regex sqlite preg-match

  

免责声明:除非我没有看到,这与this topic中描述的不同,我需要一些时间来全面解释这种情况。


很久以前我asked a question关于如何在SQLite语句中使用REGEXP运算符。默认情况下不会实现运算符,但它可以在运行时。

嗯..正如你所看到的那些日期,这对我来说已经有好几年了。不完全是在该主题的帮助下(SQLite邮件列表中的某人向我展示了一个技巧)但它运作良好。

因为preg_match()与ereg()的工作方式不同(正如我所听到的),通过在第一次匹配后立即返回,我采取了额外的预防措施,然后通过排序REGEXES来填充SQLite数据库(我确定这个从最长(更具体)到最短(更通用),不是正确的复数形式。

没什么大不了的,只是使用strlen()的简单uasort()。

考虑到一个虚构的电影管理目录,其中有两个网址,例如management/actorsmanagement/actors/add,这种排序技巧使我在访问第一个网址时避免误报并让SQLite以第二个响应结果集只是因为它们都具有相同的不可变部分management/actors

这是当前的实施:

$this -> dbh
      -> sqliteCreateFunction(

            'REGEXP',

            function( $r, $s ) {

                return ( preg_match( sprintf( '@^%s$@i', $r ), $s ) != 0 );
            },

            2
);

$ this - > dbh 使用了PDO实例的class属性。

现在情况有所不同,因为这种排序技巧没有考虑一种可能性:最通用的两条路线也是最长的路线。例如:management/actors/addmanagement/actors/overview

从概念上讲,第二条路线更通用,因为它指的是一个列出所有演员的简单仪表板,应该放在底部。实际上它只是management/actors的别名。

第二条路线更具体,因为它路由负责的表格添加新记录,因此应该到顶部

这些路由是根据围绕Controller类的PHP文档注释进行分析的,如下所示:

/**
 * Overview
 *
 * !Route    GET,    management/actors
 * !Route    GET,    management/actors/overview
 */
final public function overview() {}

/**
 * Add
 *
 * !Route    GET,    management/actors/add
 */
final public function add() {}

按顺序排列:

management/actors
management/actors/overview
management/actors/add

因为我需要识别Action方法,所以它们在不同的数组索引中构造,并且类方法名称为键:

Array(

    'overview' => array(

        [0] => management/actors
        [1] => management/actors/overview
    ),

    'add' => array(
        [0] => 'management/actors/add'
    )
)

就像我说排序有效并且可以使这个结构成为:

Array(

    'overview' => array(

        [0] => management/actors/overview
        [1] => management/actors
    ),

    'add' => array(
        [0] => 'management/actors/add'
    )
)

但由于SQLite REGEX运算符的preg_match()实现,整个组件无法工作。

到目前为止,我设法解决此问题的唯一方法是开发像这样的Controller类:

/**
 * Add
 *
 * !Route    GET,    management/projects/add
 */
final public function add() {}

/**
 * Overview
 *
 * !Route    GET,    management/projects
 * !Route    GET,    management/projects/overview
 */
final public function overview() {}

我的意思是,顺序相反。

精细!所有应用程序都以某种方式有其自身的奇怪之处,我可以忍受这种情况,但是,将来,其他人可能会打开这些代码并给它一些维护,可能不会意识到这种限制。

那说(最后)我想知道是否有办法增加preg_match()的暴食并使其不会在第一次正面发生时停止并且像ereg那样匹配最长的可能,或者至少我认为它是的,我从来没有看到它在行动。

或者替代解决方案,当然:p

根据评论中的要求,REGEXES的一些示例,按照它们在SQLite数据库中插入的顺序列出(排序后):

management/projects/overview\b(.*?)
management/projects/add\b(.*?)
management/projects\b(.*?)

他们是非常简单的REGEXES。它们主要匹配Request URI。在REGEX的末尾,我只有一个边界来区分固定字符串文本和可能存在的变量部分(如Xdebug剖析GET参数)

0 个答案:

没有答案