This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch between in repository https://gitbox.apache.org/repos/asf/camel.git
commit 4d17a602e3424e84ea095931908aa11750192513 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Jan 15 21:19:21 2026 +0100 simple language - add between --- .../modules/languages/pages/simple-language.adoc | 1 + .../camel/language/simple/SimpleConstants.java | 3 ++ .../language/simple/SimpleExpressionBuilder.java | 37 ++++++++++++++++++++++ .../simple/ast/SimpleFunctionExpression.java | 31 +++++++++++++++++- .../apache/camel/language/simple/SimpleTest.java | 31 ++++++++++++++++++ 5 files changed, 102 insertions(+), 1 deletion(-) diff --git a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc index c883e34d2fb6..7fb4a3caaa20 100644 --- a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc +++ b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc @@ -270,6 +270,7 @@ If the number is negative, then the returned string is clipped from the ending. |substringBefore(exp,before) |String |Returns a substring of the message body/expression that comes before. Returns null if nothing comes before. |substringAfter(exp,before) |String |Returns a substring of the message body/expression that comes after. Returns null if nothing comes after. +|substringBetween(exp,after,before) |String |Returns a substring of the message body/expression that are between before and after. Returns null if nothing comes between. |collate(group) |List |The collate function iterates the message body and groups the data into sub lists of specified size. This can be used with the diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java index 57dd03120f8d..6ba4fa4d8666 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java @@ -183,6 +183,9 @@ public final class SimpleConstants { public static final String SUBSTRING_AFTER = "substringAfter(exp,before)"; @Metadata(description = "Returns a random number between min (included) and max (excluded).", label = "function", javaType = "int", displayName = "Generate Random Number") + public static final String SUBSTRING_BETWEEN = "substringBetween(exp,before,after)"; + @Metadata(description = "Returns a substring of the message body/expression that are between before and after. Returns null if nothing comes between.", + label = "function", javaType = "String") public static final String RANDOM = "random(min,max)"; @Metadata(description = "The skip function iterates the message body and skips the first number of items." + " This can be used with the Splitter EIP to split a message body and skip the first N number of items.", diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java index c3ba27e19e42..ef65aad8acee 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java @@ -828,6 +828,43 @@ public final class SimpleExpressionBuilder { }; } + /** + * Returns the substring from the given expression that are between after and before + */ + public static Expression substringBetweenExpression(final String expression, final String after, final String before) { + return new ExpressionAdapter() { + private Expression exp; + private Expression expAfter; + private Expression expBefore; + + @Override + public void init(CamelContext context) { + exp = context.resolveLanguage("simple").createExpression(expression); + exp.init(context); + expAfter = ExpressionBuilder.simpleExpression(after); + expAfter.init(context); + expBefore = ExpressionBuilder.simpleExpression(before); + expBefore.init(context); + } + + @Override + public Object evaluate(Exchange exchange) { + String body = exp.evaluate(exchange, String.class); + if (body == null) { + return null; + } + String aft = expAfter.evaluate(exchange, String.class); + String bef = expBefore.evaluate(exchange, String.class); + return StringHelper.between(body, aft, bef); + } + + @Override + public String toString() { + return "substringBetween(" + expression + "," + after + "," + before + ")"; + } + }; + } + /** * Hashes the value using the given algorithm */ diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java index db2c29fa6309..ac36da491678 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java @@ -830,6 +830,35 @@ public class SimpleFunctionExpression extends LiteralExpression { } return SimpleExpressionBuilder.substringAfterExpression(exp1, after); } + remainder = ifStartsWithReturnRemainder("substringBetween(", function); + if (remainder != null) { + String values = StringHelper.before(remainder, ")"); + if (values == null || ObjectHelper.isEmpty(values)) { + throw new SimpleParserException( + "Valid syntax: ${substringBetween(before,after)} or ${substringAfter(exp,before,after)} was: " + + function, + token.getIndex()); + } + String[] tokens = StringQuoteHelper.splitSafeQuote(values, ',', false); + if (tokens.length < 2 || tokens.length > 3) { + throw new SimpleParserException( + "Valid syntax: ${substringBetween(before,after)} or ${substringAfter(exp,before,after)} was: " + + function, + token.getIndex()); + } + String exp1 = "${body}"; + String after; + String before; + if (tokens.length == 3) { + exp1 = tokens[0]; + after = tokens[1]; + before = tokens[2]; + } else { + after = tokens[0]; + before = tokens[1]; + } + return SimpleExpressionBuilder.substringBetweenExpression(exp1, after, before); + } // random function remainder = ifStartsWithReturnRemainder("random(", function); @@ -906,7 +935,7 @@ public class SimpleFunctionExpression extends LiteralExpression { remainder = ifStartsWithReturnRemainder("trim(", function); if (remainder != null) { String exp = null; - String value = StringHelper.before(remainder, ")"); + String value = StringHelper.beforeLast(remainder, ")"); if (ObjectHelper.isNotEmpty(value)) { exp = StringHelper.removeQuotes(value); } diff --git a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java index 2a1a488899d7..9b281eb35016 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java @@ -2604,6 +2604,37 @@ public class SimpleTest extends LanguageTestSupport { assertEquals(" World", s); } + @Test + public void testSubstringBetween() { + exchange.getMessage().setBody("Hello big great World"); + + Expression expression = context.resolveLanguage("simple").createExpression("${substringBetween('Hello','World')}"); + String s = expression.evaluate(exchange, String.class); + assertEquals(" big great ", s); + + expression = context.resolveLanguage("simple").createExpression("${substringBetween('Hello ',' World')}"); + s = expression.evaluate(exchange, String.class); + assertEquals("big great", s); + + expression = context.resolveLanguage("simple").createExpression("${substringBetween(${body},'big ',' World')}"); + s = expression.evaluate(exchange, String.class); + assertEquals("great", s); + + expression = context.resolveLanguage("simple").createExpression("${trim(${substringBetween(${body},'big','World')})}"); + s = expression.evaluate(exchange, String.class); + assertEquals("great", s); + + expression = context.resolveLanguage("simple").createExpression("${substringBetween('Hello','Unknown')}"); + s = expression.evaluate(exchange, String.class); + assertNull(s); + + exchange.getMessage().setHeader("place", "Hello"); + exchange.getMessage().setHeader("place2", "great"); + expression = context.resolveLanguage("simple").createExpression("${substringBetween(${body},${header.place},${header.place2})}"); + s = expression.evaluate(exchange, String.class); + assertEquals(" big ", s); + } + @Test public void testConcat() { exchange.getMessage().setBody("Hello");
