uCalc API Version: 2.1.3-preview.2 Released: 6/17/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.

Optional Parts

Product: 

Class: 

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.

Remarks

🧩 Conditional Patterns: Optional Parts

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.

// 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.


Capturing Optional Values

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.

💎 The Power of Conditional Replacements

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.

SyntaxNameBehavior
{var: ...}Positive ConditionThe content after the colon is inserted only if {var} captured a value.
{!var: ...}Fallback ContentThe content after the colon is inserted only if {var} is empty (did not capture a value).

Example: Providing a Default Value

Let's parse log entries. If a log level is not specified, we want to default to "INFO".

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 presentConsole.WriteLine(t.Transform("Log: ERROR File not found"));// Case 2: Level is missing, so the fallback is usedConsole.WriteLine(t.Transform("Log: System started successfully"));}

This declarative approach is far cleaner than writing if/else logic in a callback.


⚠️ Common Pitfall: Escaping Brackets

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.

  • Incorrect: Read [ {content} ] (This defines an optional part)
  • Correct: Read '[' {content} ']' (This matches the literal text Read [ ... ])

💡 Why uCalc? (Comparative Analysis)

  • vs. Regex (?):

    • Readability: In Regex, making a group optional requires parentheses and a question mark, like (optional part)?. uCalc's [optional part] syntax is visually cleaner and aligns with common grammar notation forms (like EBNF).
    • Conditional Replacements: Standard Regex has no simple way to say, "Insert this prefix text only if capture group 1 was matched." You would typically need to write a callback function in your host language (C#, C++, etc.) to handle this logic. uCalc's {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):

    • Manually parsing text with optional components requires procedural 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.

Examples

A basic pattern demonstrating how an optional word affects the match.
				
					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.
				
					#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;
}
				
			
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
				
			
MATCHED found.
MATCHED found.
Parses log entries to extract an optional error code, providing a default status when it's missing by using the `{!var:...}` fallback syntax.
				
					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
				
					#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;
}
				
			
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
				
			
Status:ERROR | Msg:File not found
Status:INFO | Msg:System started successfully