@@ -306,4 +306,53 @@ public void testRexMaxMatchConfigurableLimit() throws IOException {
306306 new ClusterSetting (PERSISTENT , Settings .Key .PPL_REX_MAX_MATCH_LIMIT .getKeyValue (), null ));
307307 }
308308 }
309+
310+ @ Test
311+ public void testRexNestedCaptureGroupsBugFix () throws IOException {
312+ JSONObject resultWithNested =
313+ executeQuery (
314+ String .format (
315+ "source=%s | rex field=email"
316+ + " \\ \" (?<user>[^@]+)@(?<domain>(pyrami|gmail|yahoo))\\ \\ \\ \\ .(?<tld>(com|org|net))\\ \" "
317+ + " | fields user, domain, tld | head 1" ,
318+ TEST_INDEX_ACCOUNT ));
319+
320+ assertEquals (1 , resultWithNested .getJSONArray ("datarows" ).length ());
321+ assertEquals (
322+ "amberduke" ,
323+ resultWithNested
324+ .getJSONArray ("datarows" )
325+ .getJSONArray (0 )
326+ .get (0 )); // user should be "amberduke"
327+ assertEquals (
328+ "pyrami" ,
329+ resultWithNested
330+ .getJSONArray ("datarows" )
331+ .getJSONArray (0 )
332+ .get (1 )); // domain should be "pyrami", NOT "amberduke"
333+ assertEquals (
334+ "com" ,
335+ resultWithNested
336+ .getJSONArray ("datarows" )
337+ .getJSONArray (0 )
338+ .get (2 )); // tld should be "com", NOT "pyrami"
339+
340+ // More complex nested alternation
341+ JSONObject complexNested =
342+ executeQuery (
343+ String .format (
344+ "source=%s | rex field=firstname"
345+ + " \\ \" (?<initial>(A|B|C|D|E))[a-z]*(?<suffix>(ley|nne|ber|ton|son))\\ \" |"
346+ + " fields initial, suffix | head 1" ,
347+ TEST_INDEX_ACCOUNT ));
348+
349+ if (!complexNested .getJSONArray ("datarows" ).isEmpty ()) {
350+ String initial = complexNested .getJSONArray ("datarows" ).getJSONArray (0 ).getString (0 );
351+ String suffix = complexNested .getJSONArray ("datarows" ).getJSONArray (0 ).getString (1 );
352+
353+ assertTrue ("Initial should be a single letter A-E" , initial .matches ("[A-E]" ));
354+ assertTrue (
355+ "Suffix should match alternation pattern" , suffix .matches ("(ley|nne|ber|ton|son)" ));
356+ }
357+ }
309358}
0 commit comments