Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/main/java/com/dashjoin/jsonata/Jsonata.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -1628,7 +1629,7 @@ Jsonata getPerThreadInstance() {
}
}
// apply the procedure
var procName = expr.procedure.type == "path" ? expr.procedure.steps.get(0).value : expr.procedure.value;
var procName = "path".equals(expr.procedure.type) ? expr.procedure.steps.get(0).value : expr.procedure.value;

// Error if proc is null
if (proc==null)
Expand Down Expand Up @@ -1755,9 +1756,9 @@ Jsonata getPerThreadInstance() {
List _res = new ArrayList<>();
for (String s : (List<String>)validatedArgs) {
//System.err.println("PAT "+proc+" input "+s);
if (((Pattern)proc).matcher(s).find()) {
//System.err.println("MATCH");
_res.add(s);
if (s != null) {
Matcher matcher = ((Pattern) proc).matcher(s);
_res.add(regexClosure(matcher));
}
}
result = _res;
Expand All @@ -1779,6 +1780,21 @@ Jsonata getPerThreadInstance() {
}
return result;
}

private static Map regexClosure(Matcher matcher) {
if (matcher.find()) {
String group = matcher.group();
return Map.of(
"match", group,
"start", matcher.start(),
"end", matcher.end(),
"groups", List.of(group),
"next", (Fn0<Map>) () -> regexClosure(matcher)
);
} else {
return null;
}
}

/**
* Evaluate lambda against input data
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/dashjoin/jsonata/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,8 @@ Symbol processAST(Symbol expr) {
rest.procedure.type.equals("path") &&
rest.procedure.steps.size() == 1 &&
rest.procedure.steps.get(0).type.equals("name") &&
result.steps.get(result.steps.size() - 1).type.equals("function")) {
result.steps.get(result.steps.size() - 1).type.equals("function") &&
rest.procedure.steps.get(0).value instanceof Symbol) {
// next function in chain of functions - will override a thenable
result.steps.get(result.steps.size() - 1).nextFunction = (Symbol)rest.procedure.steps.get(0).value;
}
Expand Down
71 changes: 71 additions & 0 deletions src/test/java/com/dashjoin/jsonata/RegexTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.dashjoin.jsonata;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

public class RegexTest {
@Test
public void testEvalRegex2() {

Object data = Map.of(
"domain1.test.data", Map.of(),
"domain2.test.data", Map.of()
);
var expression = Jsonata.jsonata(
"(\n" +
" $matcher := $eval('/^(domain1)\\\\./i');\n" +
" ('domain1.test.data' ~> $matcher)[0].match;\n" +
")"
);
Object evaluate = expression.evaluate(data);
String expected = "domain1.";
Assertions.assertEquals(expected, evaluate);
}

@Test
public void testEvalRegex3() {

Object data = Map.of(
"domain1.test.data", Map.of(),
"domain2.test.data", Map.of()
);
var expression = Jsonata.jsonata(
"(\n" +
" $matcher := $eval('/^(domain1)\\\\./i');\n" +
" 'domain1.test.data' ~> $matcher" +
")"
);
// TODO: why there evaluate return list but next test return map (object). In js always return object
// maybe problem in braces, but on try.jsonata always return object
Map<String, Object> evaluate = (Map<String, Object>)(((List)expression.evaluate(data)).get(0));
Assertions.assertEquals("domain1.", evaluate.get("match"));
Assertions.assertEquals(0, evaluate.get("start"));
Assertions.assertEquals(8, evaluate.get("end"));
Assertions.assertEquals(List.of("domain1."), evaluate.get("groups"));
Assertions.assertInstanceOf(Jsonata.Fn0.class, evaluate.get("next"));
}

@Test
public void testEvalRegexNext() {

Object data = Map.of(
"domain1.test.data", Map.of(),
"domain2.test.data", Map.of()
);
var expression = Jsonata.jsonata(
"(\n" +
" $matcher := $eval('/.(domain)./i');\n" +
" ('domain1.test.domain.data.domain.a' ~> $matcher).next();\n" +
")"
);
Map<String, Object> evaluate = (Map<String, Object>)(expression.evaluate(data));
Assertions.assertEquals(".domain.", evaluate.get("match"));
Assertions.assertEquals(24, evaluate.get("start"));
Assertions.assertEquals(32, evaluate.get("end"));
Assertions.assertEquals(List.of(".domain."), evaluate.get("groups"));
Assertions.assertInstanceOf(Jsonata.Fn0.class, evaluate.get("next"));
}
}