@@ -273,6 +273,58 @@ handle_local_function(
273273 [Str , Start , Len ]
274274) when is_binary (Str ), is_integer (Start ), is_integer (Len ) ->
275275 handle_local_function (jsonata_substring , [binary_to_list (Str ), Start , Len ]);
276+ % % ---> $match(...)
277+ handle_local_function (
278+ jsonata_match ,
279+ [Str , RegExp ]
280+ ) ->
281+ {ok , R } = re :compile (
282+ any_to_list (RegExp ),
283+ [dotall , dollar_endonly , caseless ]
284+ ),
285+ Args = [global ],
286+ case re :run (any_to_list (Str ), R , [{capture , all , binary } | Args ]) of
287+ nomatch ->
288+ undefined ;
289+ {match , CaptureBinary } ->
290+ {match , CaptureIdx } =
291+ re :run (any_to_list (Str ), R , [{capture , all , index } | Args ]),
292+ match_capture_objects (CaptureBinary , CaptureIdx , [])
293+ end ;
294+ handle_local_function (
295+ jsonata_match ,
296+ [Str , RegExp , MatchLimit ]
297+ ) when is_integer (MatchLimit ) =:= false ->
298+ handle_local_function (
299+ jsonata_match ,
300+ [
301+ Str ,
302+ RegExp ,
303+ list_to_integer (any_to_list (MatchLimit ))
304+ ]
305+ );
306+ handle_local_function (
307+ jsonata_match ,
308+ [_Str , _RegExp , MatchLimit ] = Args
309+ ) when is_integer (MatchLimit ), MatchLimit < 0 ->
310+ erlang :error (
311+ " Invalid JSONata expression: Third argument of match function must evaluate to a positive number" ,
312+ [{" $match" , Args }]
313+ );
314+ handle_local_function (
315+ jsonata_match ,
316+ [_Str , _RegExp , MatchLimit ]
317+ ) when is_integer (MatchLimit ), MatchLimit =:= 0 ->
318+ undefined ;
319+ handle_local_function (
320+ jsonata_match ,
321+ [Str , RegExp , MatchLimit ]
322+ ) when is_integer (MatchLimit ), MatchLimit > 0 ->
323+ match_capture_limit (
324+ handle_local_function (jsonata_match , [Str , RegExp ]),
325+ MatchLimit ,
326+ []
327+ );
276328% % -------> fall through to unsupported
277329handle_local_function (FunctionName , Args ) ->
278330 erlang :error (jsonata_unsupported , [{FunctionName , Args }]).
@@ -347,3 +399,33 @@ iso_8601_datestamp(Timestamp) ->
347399 [Year , Month , Day , Hour , Min , Sec ]
348400 )
349401 ).
402+
403+ % %
404+ % % See test id : #d206746f9f2594a6 for more format details
405+ % % --> https://flows.red-erik.org/f/d206746f9f2594a6
406+ % %
407+ match_capture_objects ([], [], [Hd | []] = _Acc ) ->
408+ Hd ;
409+ match_capture_objects ([], [], Acc ) ->
410+ lists :reverse (Acc );
411+ match_capture_objects (
412+ [[Matched | RestMatched ] | RestBinary ],
413+ [[{MatchedIdx , _ } | _RestMatched ] | RestIndicies ],
414+ Acc
415+ ) ->
416+ CapHsh = #{
417+ <<" match" >> => Matched ,
418+ <<" index" >> => MatchedIdx ,
419+ <<" groups" >> => RestMatched
420+ },
421+ match_capture_objects (RestBinary , RestIndicies , [CapHsh | Acc ]).
422+ % %
423+ % %
424+ match_capture_limit (undefined , _ , _ ) ->
425+ undefined ;
426+ match_capture_limit (_Result , 0 , [Hd | []] = _Acc ) ->
427+ Hd ;
428+ match_capture_limit (_Result , 0 , Acc ) ->
429+ lists :reverse (Acc );
430+ match_capture_limit ([HD | Rest ], MatchLimit , Acc ) ->
431+ match_capture_limit (Rest , MatchLimit - 1 , [HD | Acc ]).
0 commit comments