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");

Reply via email to