【问题标题】:regex scan files for specific contents正则表达式扫描文件以获取特定内容
【发布时间】:2022-01-22 13:21:14
【问题描述】:

我正在尝试读取我所有的项目文件,它的内容是为了检测一些字符串。

我现在有一段工作代码,但有一些缺失的部分。

目标是扫描我的所有文件,并在扫描文件中出现某些项目时将它们添加到数据库中。

例如;

我有一些这样的代码:

@can('event-tools::menu.view') 那么它应该将event-tools::menu.view 作为“找到的字符串”返回。

我也有$this->middleware('can:access registration check');之类的东西,那么它也应该检测到access registration check

我目前使用正则表达式来扫描文件内容,如下所示:

[^\w](@can|hasPermissionTo|hasDirectPermission)\(\s*(?P<quote>['"])(?P<string>(?:\\k{quote}|(?!\k{quote}).)*)\k{quote}\s*[\),]

有谁能帮忙解决这个问题吗?或者我是否应该使用其他方法?

我使用以下方法检查匹配项:

preg_match_all("/$stringPattern/siU", $fileContents, $matches)

【问题讨论】:

    标签: php regex


    【解决方案1】:

    您可以使用branch reset group 并使用具有相同命名组的交替来匹配两种不同的格式。

    (?|(?:@can|hasPermissionTo|hasDirectPermission)\(\s*(?P<quote>['"])(?P<string>.*?)\1\)|\((?P<quote>['"])can:(?P<string>.*?)\1\)|\(\[[^][]*(?P<quote>['"])can:(?P<string>.*?)\1[^][]*]\))
    

    部分模式,使用 2 个更改 | 用于 3 个不同的变化:

    • (?|分支重置组
      • (?:@can|hasPermissionTo|hasDirectPermission) 匹配 1 个备选方案
      • \(\s* 匹配 ( 和可选的空白字符
      • (?P&lt;quote&gt;['"]) 匹配组中的 '" quote
      • (?P&lt;string&gt;.*?)\1string 匹配尽可能少的字符,直到在组 quote 中捕获相同的引号
      • \)匹配)
      • |或者
      • \(匹配(
      • (?P&lt;quote&gt;['"]) - 和以前一样
      • can: 逐字匹配(或对多个单词再次使用交替)
      • (?P&lt;string&gt;.*?)\1 - 和以前一样
      • \)匹配)
      • |或者
      • \(\[匹配([
      • [^][]* 匹配除 [] 之外的任何字符
      • (?P&lt;quote&gt;['"])和以前一样
      • can: 字面匹配
      • (?P&lt;string&gt;.*?)\1和以前一样
      • [^][]*]\) 匹配除 [ 之外的任何字符 ] 使用否定字符类,然后匹配 ])
    • )关闭分支重置组

    查看regex demo

    $re = '/(?|(?:@can|hasPermissionTo|hasDirectPermission)\(\s*(?P<quote>[\'"])(?P<string>.*?)\1\)|\((?P<quote>[\'"])can:(?P<string>.*?)\1\)|\(\[[^][]*(?P<quote>[\'"])can:(?P<string>.*?)\1[^][]*]\))/';
    $str = <<<'STR'
    @can('event-tools::menu.view')
    $this->middleware('can:access registration check');
    Route::prefix('administration')->middleware(['auth', 'verified', 'can:access admin area'])->group(static function () {
    STR;
    
    $result = preg_match_all($re, $str, $matches);
    print_r($matches["string"]);
    

    输出

    Array
    (
        [0] => event-tools::menu.view
        [1] => access registration check
        [2] => access admin area
    )
    

    【讨论】:

    • 通过尝试理解您编写的代码,我认为是这样的; (?|(?:@can|hasPermissionTo|hasDirectPermission)\(\s*(?P&lt;quote&gt;['"])(?P&lt;string&gt;.*?)\1\)|\((?P&lt;quote&gt;['"])can:(?P&lt;string&gt;.*?)\1\)|(?P&lt;quote&gt;['"])can:(?P&lt;string&gt;.*?)\1) 可能是解决方案?
    • @Robin 你可以这样写是的,如果你不想要一个 if 应该在外部 ([]) 之间的规则
    • 我认为这样的规则会更安全
    • @Robin 对于这种情况,你可以写成 (?|(?:@can|hasPermissionTo|hasDirectPermission)\(\s*(?P&lt;quote&gt;['"])(?P&lt;string&gt;.*?)\1\)|\((?P&lt;quote&gt;['"])can:(?P&lt;string&gt;.*?)\1\)|\(\[[^][]*(?P&lt;quote&gt;['"])can:(.*?)\1[^][]*]\)) regex101.com/r/ZZQ70O/1
    • @Robin 我更新了之前的评论,应该是regex101.com/r/oJSyU7/1
    猜你喜欢
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 2011-02-11
    • 2020-12-14
    • 2012-12-16
    • 1970-01-01
    相关资源
    最近更新 更多