猿问

一个正则表达式来匹配 php 类的开始和结束字符内的内容

我无法找到与 php 类的开始和结束字符(分别为 { 和 })匹配的正则表达式。如果 { 和 } 位于 php 注释内,正则表达式也不应该匹配它们,换句话说,如果 { 或 } 前面有除空格之外的任何字符,则它不应该匹配。


我想我应该使用负向查找,但我对正则表达式有点生疏,到目前为止我还没有找到解决方案。


这是我的测试字符串:


<?php



namespace Ling\Light_TaskScheduler\Service;



/**

 * The LightTaskSchedulerService class. :{

 */

class LightTaskSchedulerService

{


    /**

     *

     * This method IS the task manager.

     * See the @page(Light_TaskScheduler conception notes) for more details.

     *

     */

    public function run()

    {

        $executionMode = $this->options['executionMode'] ?? "lastOnly";

        $this->logDebug("Executing run method with execution mode \"$executionMode\".");



    }



}



// this can happen in comments: }, why

// more stuff








我的模式目前不起作用,是这样的:


    if(preg_match('!^\s*\{\s*(.*)(?<![^\s]*)\}!ms', $c, $match)){

        a($match);

    }

所以,我使用了多行修饰符“m”,因为我们需要解析多行字符串,然后我使用了“s”修饰符,以便点与换行符匹配,但然后在部分 (?<![^\s ]*) 似乎不起作用。我基本上是想说,如果“}”字符前面没有空格,则不匹配它。


@Wiktor Stribiżew:我尝试了这种模式,但它仍然不起作用:!^\s*\{\s*(.*)(?<!\S)\}!ms


考虑到 Tim Biegeleisen 的评论,我可能会采取一种更简单的方法,例如先删除注释,然后执行更简单的 regex !^\s*\{\s*(.*)\}!ms,我知道这会起作用。


但是,如果有人知道可以执行此操作的正则表达式,我将有兴趣查看它。


暮色呼如
浏览 143回答 1
1回答

慕妹3242003

正如人们已经在评论部分指出的那样:正则表达式可能不是执行此操作的最佳解决方案。不管怎样,你要求它,我在下面的课程中测试了它。// 1) without class check -> this does not work with code on line with opening {preg_match('/(?:^{(?!\r?\n?\s*\*\/)|{\s*$(?!\r?\n?\s*\*\/)).+^\s*}(?!\r?\n?\s*\*\/)/ms', $c, $match);// 2) with class check -> this should always workpreg_match('/^[\s\w]+?(?:{(?!\r?\n?\s*\*\/)|{\s*$(?!\r?\n?\s*\*\/)).+^\s*}(?!\r?\n?\s*\*\/)/ms', $c, $match);// 3) with class check and capturing the second part (non-class-definition) separately -> this should always workpreg_match('/^[\s\w]+?((?:{(?!\r?\n?\s*\*\/)|{\s*$(?!\r?\n?\s*\*\/)).+^\s*}(?!\r?\n?\s*\*\/))/ms', $c, $match);我建议使用 3)。/** * The LightTaskSchedulerService class. :{ */class LightTaskSchedulerService implements TaskSchedulerService {{    /**     *     * This method IS the task manager.     * See the @page(Light_TaskScheduler conception notes) for more details.     *     */    public function run()    {        $executionMode = $this->options['executionMode'] ?? "lastOnly";        $this->logDebug("Executing run method with execution mode \"$executionMode\".");        if ($foo) {            doBar($foo);        }        /* multiline */        // simple one line comment        // simple one line comment { }        # another comment        # another comment}} {        # another comment{/*}*///}#}/*}*//*{*//*}*//*}*/    }}// this can happen in comments:}, why// more stuff/* multiline hello} hello{}*/# singleline{#}//}/*}*//**}*/输出:Array(    [0] => {{    /**     *     * This method IS the task manager.     * See the @page(Light_TaskScheduler conception notes) for more details.     *     */    public function run()    {        $executionMode = $this->options['executionMode'] ?? "lastOnly";        $this->logDebug("Executing run method with execution mode \"$executionMode\".");        if ($foo) {            doBar($foo);        }        /* multiline */        // simple one line comment        // simple one line comment { }        # another comment        # another comment}} {        # another comment{/*}*///}#}/*}*//*{*//*}*//*}*/    }})您的代码不起作用,因为它有错误:未知修饰符g(for preg_match) =>preg_match_all使用$c在你的代码中不起作用,因为它不在 php 范围内写:<?php $c = <<<'EEE' ...相反在你的案例中,后面的外观不起作用,因为你不能使用+*?修饰符。参考:在php.net上,“g”未列为选项。修饰符“g”:preg_match_all我认为你甚至不需要preg_match_all一个简单的preg_match应该工作,因为无论如何你只需要这场比赛。这应该可以工作(用 PHP 7.0.1 测试)。它对我来说:preg_match('/^class\s+\w+\s*({.+(?<! )})/ms', $c, $match);// or:preg_match('/^class[^{]+({.+(?<! )})/ms', $c, $match);// or even:preg_match('^{.+\r?\n}(?<! )/ms', $c, $match);print_r($match);我的正则表达式中的否定查找后面会检查本例中后面跟着的前导空格}- 在本例中右括号需要位于最左角。这将起作用,除非您希望以不同的方式进行。无论如何,你需要一个分隔符。而且您也不希望 run() 方法中的 if 语句的右大括号结束搜索。print_r$match上面第一条语句的输出preg_match:Array(    [0] => class LightTaskSchedulerService{    /**     *     * This method IS the task manager.     * See the @page(Light_TaskScheduler conception notes) for more details.     *     */    public function run()    {        $executionMode = $this->options['executionMode'] ?? "lastOnly";        $this->logDebug("Executing run method with execution mode \"$executionMode\".");        if ($foo) {            doBar($foo);        }    }}    [1] => {    /**     *     * This method IS the task manager.     * See the @page(Light_TaskScheduler conception notes) for more details.     *     */    public function run()    {        $executionMode = $this->options['executionMode'] ?? "lastOnly";        $this->logDebug("Executing run method with execution mode \"$executionMode\".");        if ($foo) {            doBar($foo);        }    }})
随时随地看视频慕课网APP
我要回答