uCalc API Version: 2.1.3-preview.2 Released: 6/16/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
Executing Logic in Replacements
Product:
Class:
Learn to execute expressions and call functions within replacement strings using the powerful {@Eval} and {@@Eval} directives.
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.
// 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.
// 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.
// 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}(ifvalis123, this would result in123123).
💡 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.
t.FromTo("Qty: {@Number:qty}, Price: {@Number:price}", "{@Self}, Total: {@Eval: Double(qty) * Double(price)}");Examples
A succinct example that performs a simple unit conversion from inches to centimeters using `{@Eval}`.
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. 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."));
#include
#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. #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; }
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. 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
A practical example that calculates line-item totals for a list of products by capturing quantity and price.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// Rule to find quantity and price, then calculate total.
// Note the explicit Double() conversion for the captured text variables.
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 using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // Rule to find quantity and price, then calculate total. // Note the explicit Double() conversion for the captured text variables. 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));
#include
#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() conversion for the captured text variables.
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 #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() conversion for the captured text variables. 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; }
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() conversion for the captured text variables.
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 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() conversion for the captured text variables. 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
Internal Test: Verifies that `{@@Eval}` can correctly parse and evaluate an expression that is itself captured from the text.
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. 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));
#include
#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. #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; }
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. 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