regex scan files for specific contents
You could make use of a branch reset group and match the 2 different formats using an alternation with the same named groups.
(?|(?:@can|hasPermissionTo|hasDirectPermission)\(\s*(?P<quote>['"])(?P<string>.*?)\1\)|\((?P<quote>['"])can:(?P<string>.*?)\1\)|\(\[[^][]*(?P<quote>['"])can:(?P<string>.*?)\1[^][]*]\))
The pattern in parts, using 2 alterations |
for 3 different variations:
-
(?|
Branch reset group-
(?:@can|hasPermissionTo|hasDirectPermission)
Match 1 of the alternatives -
\(\s*
Match(
and optional whitespace chars -
(?P<quote>['"])
Match either'
or"
in group quote -
(?P<string>.*?)\1
Group string Match as least as possible chars till the same quote that was captured in group quote -
\)
Match)
-
|
Or -
\(
Match(
-
(?P<quote>['"])
- Same as before -
can:
Match literally (Or use an alternation again for multiple words) -
(?P<string>.*?)\1
- Same as before -
\)
Match)
-
|
Or -
\(\[
Match([
-
[^][]*
Match any char except[
and]
-
(?P<quote>['"])
Same as before -
can:
Match literally -
(?P<string>.*?)\1
Same as before -
[^][]*]\)
Match any char except[
]
using a negated characer class, then match])
-
-
)
Close branch reset group
See a 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"]);
Output
Array
(
[0] => event-tools::menu.view
[1] => access registration check
[2] => access admin area
)