Skip to content

Commit 8cae16a

Browse files
committed
ISSUES-91: fix regex matcher body and next func
1 parent 78ce14c commit 8cae16a

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

src/main/java/com/dashjoin/jsonata/Jsonata.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.function.BiFunction;
3838
import java.util.function.Function;
3939
import java.util.function.Supplier;
40+
import java.util.regex.Matcher;
4041
import java.util.regex.Pattern;
4142
import java.util.stream.Collectors;
4243

@@ -1753,11 +1754,11 @@ Jsonata getPerThreadInstance() {
17531754
}
17541755
} else if (proc instanceof Pattern) {
17551756
List _res = new ArrayList<>();
1756-
for (String s : (List<String>)validatedArgs) {
1757+
for (Object s : (List)validatedArgs) {
17571758
//System.err.println("PAT "+proc+" input "+s);
1758-
if (((Pattern)proc).matcher(s).find()) {
1759-
//System.err.println("MATCH");
1760-
_res.add(s);
1759+
if (s instanceof String) {
1760+
Matcher matcher = ((Pattern) proc).matcher((String) s);
1761+
_res.add(regexClosure(matcher));
17611762
}
17621763
}
17631764
result = _res;
@@ -1779,6 +1780,21 @@ Jsonata getPerThreadInstance() {
17791780
}
17801781
return result;
17811782
}
1783+
1784+
private static Map regexClosure(Matcher matcher) {
1785+
if (matcher.find()) {
1786+
String group = matcher.group();
1787+
return Map.of(
1788+
"match", group,
1789+
"start", matcher.start(),
1790+
"end", matcher.end(),
1791+
"groups", List.of(group),
1792+
"next", (Fn0<Map>) () -> regexClosure(matcher)
1793+
);
1794+
} else {
1795+
return null;
1796+
}
1797+
}
17821798

17831799
/**
17841800
* Evaluate lambda against input data

src/main/java/com/dashjoin/jsonata/Parser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,8 @@ Symbol processAST(Symbol expr) {
998998
rest.procedure.type.equals("path") &&
999999
rest.procedure.steps.size() == 1 &&
10001000
rest.procedure.steps.get(0).type.equals("name") &&
1001-
result.steps.get(result.steps.size() - 1).type.equals("function")) {
1001+
result.steps.get(result.steps.size() - 1).type.equals("function") &&
1002+
rest.procedure.steps.get(0).value instanceof Symbol) {
10021003
// next function in chain of functions - will override a thenable
10031004
result.steps.get(result.steps.size() - 1).nextFunction = (Symbol)rest.procedure.steps.get(0).value;
10041005
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.dashjoin.jsonata;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
public class RegexTest {
10+
@Test
11+
public void testEvalRegex2() {
12+
13+
Object data = Map.of(
14+
"domain1.test.data", Map.of(),
15+
"domain2.test.data", Map.of()
16+
);
17+
var expression = Jsonata.jsonata(
18+
"(\n" +
19+
" $matcher := $eval('/^(domain1)\\\\./i');\n" +
20+
" ('domain1.test.data' ~> $matcher)[0].match;\n" +
21+
")"
22+
);
23+
Object evaluate = expression.evaluate(data);
24+
String expected = "domain1.";
25+
Assertions.assertEquals(expected, evaluate);
26+
}
27+
28+
@Test
29+
public void testEvalRegex3() {
30+
31+
Object data = Map.of(
32+
"domain1.test.data", Map.of(),
33+
"domain2.test.data", Map.of()
34+
);
35+
var expression = Jsonata.jsonata(
36+
"(\n" +
37+
" $matcher := $eval('/^(domain1)\\\\./i');\n" +
38+
" 'domain1.test.data' ~> $matcher" +
39+
")"
40+
);
41+
// TODO: why there evaluate return list but next test return map (object). In js always return object
42+
// maybe problem in braces, but on try.jsonata always return object
43+
Map<String, Object> evaluate = (Map<String, Object>)(((List)expression.evaluate(data)).get(0));
44+
Assertions.assertEquals("domain1.", evaluate.get("match"));
45+
Assertions.assertEquals(0, evaluate.get("start"));
46+
Assertions.assertEquals(8, evaluate.get("end"));
47+
Assertions.assertEquals(List.of("domain1."), evaluate.get("groups"));
48+
Assertions.assertInstanceOf(Jsonata.Fn0.class, evaluate.get("next"));
49+
}
50+
51+
@Test
52+
public void testEvalRegexNext() {
53+
54+
Object data = Map.of(
55+
"domain1.test.data", Map.of(),
56+
"domain2.test.data", Map.of()
57+
);
58+
var expression = Jsonata.jsonata(
59+
"(\n" +
60+
" $matcher := $eval('/.(domain)./i');\n" +
61+
" ('domain1.test.domain.data.domain.a' ~> $matcher).next();\n" +
62+
")"
63+
);
64+
Map<String, Object> evaluate = (Map<String, Object>)(expression.evaluate(data));
65+
Assertions.assertEquals(".domain.", evaluate.get("match"));
66+
Assertions.assertEquals(24, evaluate.get("start"));
67+
Assertions.assertEquals(32, evaluate.get("end"));
68+
Assertions.assertEquals(List.of(".domain."), evaluate.get("groups"));
69+
Assertions.assertInstanceOf(Jsonata.Fn0.class, evaluate.get("next"));
70+
}
71+
}

0 commit comments

Comments
 (0)