Executing Logic in Replacements

Learn to execute expressions and call functions within replacement strings using the powerful {@Eval} and {@@Eval} directives.

Product: 

Class: 

Warning

uCalc API Preview Release Notice:The uCalc engine has successfully transitioned to modern cross-platform environments.The next phase envolves some structural changes, performance optimizations, and API refinements.The API is subject to breaking changes prior to the stable release. Please evaluate the preview version thoroughly before production use.

Remarks

🧠 Executing Logic in Replacements

Traditional find-and-replace tools are typically limited to static text and simple backreferences ($1, $2). uCalc's Transformer elevates this by allowing you to execute complex logic, perform calculations, and call functions directly within the replacement string. This turns a simple text substitution into a dynamic, intelligent transformation.

The engine for this capability is a set of special pattern methods that evaluate expressions at different stages of the transformation process.

The Core Tools: {@Eval}, {@@Eval}, and {@Exec}

1. {@Eval}: The Workhorse for Dynamic Values

The {@Eval} directive is the most common tool for executing logic. It evaluates a fixed expression using dynamic values captured from the current match. For performance, the expression is parsed only once when the rule is created.

To use a variable captured in your pattern (e.g., {qty}), simply refer to it by name inside the Eval block without curly braces.

using uCalcSoftware;

var uc = new uCalc();

// The expression 'Double(qty) * Double(price)' is fixed.
// The values for 'qty' and 'price' change with each match.
t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
"{@Self}, Total: {@Eval: Double(qty) * Double(price)}");

2. {@@Eval}: The Power Tool for Dynamic Formulas

The {@@Eval} directive (with a double @@) is for meta-programming scenarios where the expression itself is captured from the source text. It parses and evaluates its content every single time a match is found.

This allows you to create a transformer that can solve mathematical problems embedded in a string.

using uCalcSoftware;

var uc = new uCalc();

// The variable {formula} captures the text "10 * (5-2)".
// {@@Eval} then executes that captured text as an expression.
t.FromTo("solve({formula})", "{@@Eval: formula}");

3. {@Exec}: For Side Effects Only

The {@Exec} directive is a "void" version of {@Eval}. It executes an expression but does not insert any text into the replacement string. It is used exclusively for side effects, such as incrementing a counter, logging information, or setting a Variable that will be used by another rule.

using uCalcSoftware;

var uc = new uCalc();

// This rule finds a word but inserts nothing into the text as a replacement.
// Its only purpose is to increment the 'word_count' variable.
t.FromTo("{@Alpha}", "{@Self}{@Exec: word_count++}");

⚠️ Important: Type Conversion

All variables captured from a pattern, even those from {@Number:val}, are text strings. Before you can use them in a mathematical calculation inside an {@Eval} block, you must explicitly convert them to a numeric type using functions like Double() or Int().

  • Correct: {@Eval: Double(val) * 2}
  • Incorrect: {@Eval: val * 2} (if val is 123, this would result in 123123).

💡 Why uCalc? (Comparative Analysis)

In most programming environments, performing logic during a regex replacement requires writing a separate callback function (like a MatchEvaluator in C#). This separates the logic from the pattern and can be verbose.

C# MatchEvaluator Approach:

string ProcessMatch(Match m){    int qty = int.Parse(m.Groups["qty"].Value);    double price = double.Parse(m.Groups["price"].Value);    return m.Value + ", Total: " + (qty * price);}Regex.Replace(input, @"Qty: (?<qty>\d+), Price: (?<price>[\d\.]+)", ProcessMatch);

The uCalc Advantage:uCalc's declarative approach allows the logic to live directly and cleanly within the replacement string, resulting in more concise and readable rules.

using uCalcSoftware;

var uc = new uCalc();

t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
"{@Self}, Total: {@Eval: Double(qty) * Double(price)}");

Examples

Performing a simple unit conversion from inches to centimeters using `{@Eval}`.

ID: 1217

				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();

// Capture a number followed by 'in' and convert it.
// Note: `len` is a string, so we must use Double(len) for the calculation.
t.FromTo("{@Number:len}in", "{@Eval: Double(len) * 2.54}cm");

Console.WriteLine(t.Transform("The board is 10in long."));
				
			
The board is 25.4cm long.
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;

   // Capture a number followed by 'in' and convert it.
   // Note: `len` is a string, so we must use Double(len) for the calculation.
   t.FromTo("{@Number:len}in", "{@Eval: Double(len) * 2.54}cm");

   cout << t.Transform("The board is 10in long.") << endl;
}
				
			
The board is 25.4cm long.
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      
      '// Capture a number followed by 'in' and convert it.
      '// Note: `len` is a string, so we must use Double(len) for the calculation.
      t.FromTo("{@Number:len}in", "{@Eval: Double(len) * 2.54}cm")
      
      Console.WriteLine(t.Transform("The board is 10in long."))
   End Sub
End Module
				
			
The board is 25.4cm long.
A practical example that calculates line-item totals for a list of products by capturing quantity and price.

ID: 1218

				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
// Rule to find quantity and price, then calculate total.
// Note the explicit Double() to convert the captured numerical
// values as text into double-precision numbers for {@Eval}.
t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
"{@Self}, Total: {@Eval: Double(qty) * Double(price)}");

var invoice = """
Item: Book, Qty: 3, Price: 15.00
Item: Pen, Qty: 10, Price: 1.50
""";

Console.WriteLine(t.Transform(invoice));
				
			
Item: Book, Qty: 3, Price: 15.00, Total: 45
Item: Pen, Qty: 10, Price: 1.50, Total: 15
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   // Rule to find quantity and price, then calculate total.
   // Note the explicit Double() to convert the captured numerical
   // values as text into double-precision numbers for {@Eval}.
   t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
   "{@Self}, Total: {@Eval: Double(qty) * Double(price)}");

   auto invoice = R"(Item: Book, Qty: 3, Price: 15.00
Item: Pen, Qty: 10, Price: 1.50)";

   cout << t.Transform(invoice) << endl;
}
				
			
Item: Book, Qty: 3, Price: 15.00, Total: 45
Item: Pen, Qty: 10, Price: 1.50, Total: 15
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      '// Rule to find quantity and price, then calculate total.
      '// Note the explicit Double() to convert the captured numerical
      '// values as text into double-precision numbers for {@Eval}.
      t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}",
      "{@Self}, Total: {@Eval: Double(qty) * Double(price)}")
      
      Dim invoice = "Item: Book, Qty: 3, Price: 15.00
Item: Pen, Qty: 10, Price: 1.50"
      
      Console.WriteLine(t.Transform(invoice))
   End Sub
End Module
				
			
Item: Book, Qty: 3, Price: 15.00, Total: 45
Item: Pen, Qty: 10, Price: 1.50, Total: 15
Internal Test: Verifies that `{@@Eval}` can correctly parse and evaluate an expression that is itself captured from the text.

ID: 1220

				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();

// The variable {formula} will capture the literal text "10 * (5-2)".
// {@@Eval} then executes that text as an expression.
t.FromTo("solve({formula})", "'{formula}' is {@@Eval: formula}.");

var text = "The answer to solve(10 * (5-2))";
Console.WriteLine(t.Transform(text));
				
			
The answer to '10 * (5-2)' is 30.
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;

   // The variable {formula} will capture the literal text "10 * (5-2)".
   // {@@Eval} then executes that text as an expression.
   t.FromTo("solve({formula})", "'{formula}' is {@@Eval: formula}.");

   auto text = "The answer to solve(10 * (5-2))";
   cout << t.Transform(text) << endl;
}
				
			
The answer to '10 * (5-2)' is 30.
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      
      '// The variable {formula} will capture the literal text "10 * (5-2)".
      '// {@@Eval} then executes that text as an expression.
      t.FromTo("solve({formula})", "'{formula}' is {@@Eval: formula}.")
      
      Dim text = "The answer to solve(10 * (5-2))"
      Console.WriteLine(t.Transform(text))
   End Sub
End Module
				
			
The answer to '10 * (5-2)' is 30.