uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026
Warning
uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.
Learn how to define sections of a pattern that may or may not exist and how to create conditional replacements based on whether a match occurred.
In real-world data, not every piece of information is always present. A person might have a middle name, a log entry might have an optional error code, or a command might have an optional flag. Optional Parts are a fundamental feature of uCalc patterns that allow you to handle these variations gracefully.
The syntax is simple and intuitive: any part of a pattern enclosed in square brackets [...] is considered optional. For a detailed reference, see the main Optional parts topic.
csharp
// This pattern will match "Report" with or without the word "Detailed"
var pattern = "Generate [Detailed] Report";
This tutorial will guide you through using optional parts for flexible matching and powerful conditional replacements.
When you place a variable inside an optional block, such as [{level}], the variable will only be populated if that part of the pattern is successfully matched. If the optional part is not present in the source text, the variable will be empty.
This simple mechanism is the foundation for creating conditional logic in your replacement strings.
This is where optional parts truly shine. uCalc provides a special replacement syntax to conditionally include or exclude text based on whether an optional variable was captured. This allows you to handle default values, add optional labels, and format output dynamically, often without needing a complex callback function.
| Syntax | Name | Behavior |
|---|---|---|
{var: ...} | Positive Condition | The content after the colon is inserted only if {var} captured a value. |
{!var: ...} | Fallback Content | The content after the colon is inserted only if {var} is empty (did not capture a value). |
Let's parse log entries. If a log level is not specified, we want to default to "INFO".
csharpThis declarative approach is far cleaner than writing
using (var t = new uCalc.Transformer()) {
// Pattern: Match "Log:", an optional level, and the message.
// Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty.
t.FromTo("Log: [{level: ERROR | WARN}] {msg}",
"Status:{!level:INFO}{level} | Msg:{msg}");
// Case 1: Level is present
Console.WriteLine(t.Transform("Log: ERROR File not found"));
// Case 2: Level is missing, so the fallback is used
Console.WriteLine(t.Transform("Log: System started successfully"));
}if/else logic in a callback.
Because square brackets [ and ] are reserved for defining optional parts, if you need to match a literal square bracket in your text (e.g., in a JSON array like [1,2,3]), you must escape them by enclosing them in single quotes.
Read [ {content} ] (This defines an optional part)Read '[' {content} ']' (This matches the literal text Read [ ... ])vs. Regex (?):
(optional part)?. uCalc's [optional part] syntax is visually cleaner and aligns with common grammar notation forms (like EBNF).{var: ...} and {!var: ...} syntax handles this declaratively and directly within the replacement string, which is a major advantage in simplicity and power.vs. Native Code (If/Else):
if/else logic to check for different variations. uCalc's pattern matching is declarative. You describe what the structure looks like, including its optional parts, and the engine handles the complex branching logic for you.ID: 1204
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
t.FromTo("Log [ERROR] entry", "MATCHED");
// This matches because the optional word is present
Console.WriteLine(t.Transform("Log ERROR entry found."));
// This also matches because the word is optional
Console.WriteLine(t.Transform("Log entry found."));
MATCHED found.
MATCHED found. using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); t.FromTo("Log [ERROR] entry", "MATCHED"); // This matches because the optional word is present Console.WriteLine(t.Transform("Log ERROR entry found.")); // This also matches because the word is optional Console.WriteLine(t.Transform("Log entry found."));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
t.FromTo("Log [ERROR] entry", "MATCHED");
// This matches because the optional word is present
cout << t.Transform("Log ERROR entry found.") << endl;
// This also matches because the word is optional
cout << t.Transform("Log entry found.") << endl;
}
MATCHED found.
MATCHED found. #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; t.FromTo("Log [ERROR] entry", "MATCHED"); // This matches because the optional word is present cout << t.Transform("Log ERROR entry found.") << endl; // This also matches because the word is optional cout << t.Transform("Log entry found.") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
t.FromTo("Log [ERROR] entry", "MATCHED")
'// This matches because the optional word is present
Console.WriteLine(t.Transform("Log ERROR entry found."))
'// This also matches because the word is optional
Console.WriteLine(t.Transform("Log entry found."))
End Sub
End Module
MATCHED found.
MATCHED found. Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() t.FromTo("Log [ERROR] entry", "MATCHED") '// This matches because the optional word is present Console.WriteLine(t.Transform("Log ERROR entry found.")) '// This also matches because the word is optional Console.WriteLine(t.Transform("Log entry found.")) End Sub End Module
ID: 1205
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// Pattern: Match "Log:", an optional level, and the message.
// Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty.
t.FromTo("Log: [{level: ERROR | WARN}] {msg}",
"Status:{!level:INFO}{level} | Msg:{msg}");
// Case 1: Level is present
Console.WriteLine(t.Transform("Log: ERROR File not found"));
// Case 2: Level is missing, so the fallback is used
Console.WriteLine(t.Transform("Log: System started successfully"));
Status:ERROR | Msg:File not found
Status:INFO | Msg:System started successfully using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // Pattern: Match "Log:", an optional level, and the message. // Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty. t.FromTo("Log: [{level: ERROR | WARN}] {msg}", "Status:{!level:INFO}{level} | Msg:{msg}"); // Case 1: Level is present Console.WriteLine(t.Transform("Log: ERROR File not found")); // Case 2: Level is missing, so the fallback is used Console.WriteLine(t.Transform("Log: System started successfully"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
// Pattern: Match "Log:", an optional level, and the message.
// Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty.
t.FromTo("Log: [{level: ERROR | WARN}] {msg}",
"Status:{!level:INFO}{level} | Msg:{msg}");
// Case 1: Level is present
cout << t.Transform("Log: ERROR File not found") << endl;
// Case 2: Level is missing, so the fallback is used
cout << t.Transform("Log: System started successfully") << endl;
}
Status:ERROR | Msg:File not found
Status:INFO | Msg:System started successfully #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; // Pattern: Match "Log:", an optional level, and the message. // Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty. t.FromTo("Log: [{level: ERROR | WARN}] {msg}", "Status:{!level:INFO}{level} | Msg:{msg}"); // Case 1: Level is present cout << t.Transform("Log: ERROR File not found") << endl; // Case 2: Level is missing, so the fallback is used cout << t.Transform("Log: System started successfully") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
'// Pattern: Match "Log:", an optional level, and the message.
'// Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty.
t.FromTo("Log: [{level: ERROR | WARN}] {msg}",
"Status:{!level:INFO}{level} | Msg:{msg}")
'// Case 1: Level is present
Console.WriteLine(t.Transform("Log: ERROR File not found"))
'// Case 2: Level is missing, so the fallback is used
Console.WriteLine(t.Transform("Log: System started successfully"))
End Sub
End Module
Status:ERROR | Msg:File not found
Status:INFO | Msg:System started successfully Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() '// Pattern: Match "Log:", an optional level, and the message. '// Replacement: Use `{!level:INFO}` to insert 'INFO' if {level} is empty. t.FromTo("Log: [{level: ERROR | WARN}] {msg}", "Status:{!level:INFO}{level} | Msg:{msg}") '// Case 1: Level is present Console.WriteLine(t.Transform("Log: ERROR File not found")) '// Case 2: Level is missing, so the fallback is used Console.WriteLine(t.Transform("Log: System started successfully")) End Sub End Module