@@ -228,7 +228,56 @@ private function evaluateBracket(string $expr, mixed $value): array
228
228
return $ this ->evaluateFilter ($ innerExpr , $ value );
229
229
}
230
230
231
- // quoted strings for object keys
231
+ // comma-separated values, e.g. `['key1', 'key2', 123]` or `[0, 1, 'key']`
232
+ if (str_contains ($ expr , ', ' )) {
233
+ $ parts = $ this ->parseCommaSeparatedValues ($ expr );
234
+
235
+ $ result = [];
236
+ $ keysIndices = array_keys ($ value );
237
+ $ isList = array_is_list ($ value );
238
+
239
+ foreach ($ parts as $ part ) {
240
+ $ part = trim ($ part );
241
+
242
+ if (preg_match ('/^([ \'"])(.*)\1$/ ' , $ part , $ matches )) {
243
+ $ key = stripslashes ($ matches [2 ]);
244
+
245
+ if ($ isList ) {
246
+ foreach ($ value as $ item ) {
247
+ if (\is_array ($ item ) && array_key_exists ($ key , $ item )) {
248
+ $ result [] = $ item ;
249
+ break ;
250
+ }
251
+ }
252
+
253
+ continue ; // no results here
254
+ }
255
+
256
+ if (array_key_exists ($ key , $ value )) {
257
+ $ result [] = $ value [$ key ];
258
+ }
259
+ } elseif (preg_match ('/^-?\d+$/ ' , $ part )) {
260
+ // numeric index
261
+ $ index = (int ) $ part ;
262
+ if ($ index < 0 ) {
263
+ $ index = count ($ value ) + $ index ;
264
+ }
265
+
266
+ if ($ isList && array_key_exists ($ index , $ value )) {
267
+ $ result [] = $ value [$ index ];
268
+ continue ;
269
+ }
270
+
271
+ // numeric index on a hashmap
272
+ if (isset ($ keysIndices [$ index ]) && isset ($ value [$ keysIndices [$ index ]])) {
273
+ $ result [] = $ value [$ keysIndices [$ index ]];
274
+ }
275
+ }
276
+ }
277
+
278
+ return $ result ;
279
+ }
280
+
232
281
if (preg_match ('/^([ \'"])(.*)\1$/ ' , $ expr , $ matches )) {
233
282
$ key = stripslashes ($ matches [2 ]);
234
283
@@ -415,4 +464,44 @@ private function compare(mixed $left, mixed $right, string $operator): bool
415
464
default => false ,
416
465
};
417
466
}
467
+
468
+ private function parseCommaSeparatedValues (string $ expr ): array
469
+ {
470
+ $ parts = [];
471
+ $ current = '' ;
472
+ $ inQuotes = false ;
473
+ $ quoteChar = null ;
474
+
475
+ for ($ i = 0 ; $ i < strlen ($ expr ); $ i ++) {
476
+ $ char = $ expr [$ i ];
477
+
478
+ if ($ char === '\\' && $ i + 1 < strlen ($ expr )) {
479
+ $ current .= $ char . $ expr [++$ i ];
480
+ continue ;
481
+ }
482
+
483
+ if ('" ' === $ char || "' " === $ char ) {
484
+ if (!$ inQuotes ) {
485
+ $ inQuotes = true ;
486
+ $ quoteChar = $ char ;
487
+ } elseif ($ char === $ quoteChar ) {
488
+ $ inQuotes = false ;
489
+ $ quoteChar = null ;
490
+ }
491
+ } elseif (!$ inQuotes && $ char === ', ' ) {
492
+ $ parts [] = trim ($ current );
493
+ $ current = '' ;
494
+
495
+ continue ;
496
+ }
497
+
498
+ $ current .= $ char ;
499
+ }
500
+
501
+ if ('' !== $ current ) {
502
+ $ parts [] = trim ($ current );
503
+ }
504
+
505
+ return $ parts ;
506
+ }
418
507
}
0 commit comments