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.

Introduction

Product: 

Transformer Library

Class: 

Rule

An overview of the Rule object, the core component representing a compiled pattern and its behavioral properties in the Transformer.

Remarks

🎯 The Rule Object: A Compiled Pattern

The Rule class is the fundamental building block of the uCalc Transformer. It represents a single, compiled search pattern and its associated action, such as a replacement string or a callback. When you define a pattern with methods like FromTo() or Pattern(), the Transformer creates a Rule object internally.

By obtaining a handle to this Rule object, you gain powerful, granular control over its behavior at runtime.


⚙️ Core Concepts

  • Stateful, Configurable Objects: Unlike a simple Regex pattern (which is just a string), a Rule is a stateful object with a rich set of properties. You can programmatically control its behavior after it has been created, toggling features like case sensitivity, whitespace handling, or its active state.

  • Precedence and Order (LIFO): When a Transformer has multiple rules, their precedence is determined by a Last-In, First-Out (LIFO) order. The most recently defined rule is checked first. This allows you to build a base of general rules and then add more specific, higher-precedence rules on top of them.

  • Hierarchical Parsing: Rules can be nested using the LocalTransformer property. This allows you to create parent-child relationships where a set of "child" rules only applies to the text captured by a "parent" rule, enabling sophisticated parsing of structured, nested data.


📖 Member List

MemberDescription
ActiveGets or sets whether the rule is active and will be considered during pattern matching.
BracketSensitiveControls whether the rule respects balanced bracket pairs.
CaseSensitiveControls whether pattern matching for the rule is case-sensitive.
DescriptionGets or sets a user-defined text description for metadata and debugging.
FocusableFlags a rule's matches for inclusion/exclusion from filtered result sets.
GlobalMaximumSets a global match limit; if exceeded, the entire transformation pass is invalidated.
GlobalMinimumSets a global minimum match requirement; if not met, the entire pass is invalidated.
HasLocalTransformerChecks if the rule has a nested local transformer without creating one.
IsChildRuleDetermines if the rule belongs to a nested (local) transformer.
LocalTransformerGets a nested Transformer scoped exclusively to the text matched by this rule.
MatchesRetrieves the collection of matches found exclusively by this rule.
MaximumSets a rule-specific match limit; if exceeded, only this rule's matches are invalidated.
MinimumSets a rule-specific minimum match requirement; if not met, only this rule's matches are invalidated.
NameGets the programmatic name of the rule, derived from its pattern.
NextOverloadRetrieves the next rule in a sequence of rules that share the same starting anchor.
ParentTransformerRetrieves the parent Transformer that owns this rule.
PatternGets the original pattern string that defines the rule's matching criteria.
PrecedenceGets or sets the rule's precedence level.
QuoteSensitiveControls whether the rule respects quoted strings as atomic units.
ReleasePermanently removes the rule from the transformer.
ReplacementGets or sets the replacement string for the rule.
RewindOnChangeControls whether the transformer re-scans text after a replacement, enabling recursive transformations.
StartAfterSets the number of matches to skip before including results.
StatementSensitiveControls whether the rule respects statement separators (like semicolons or newlines).
StopAfterSets the maximum number of matches this rule will find before stopping.
TagGets or sets a user-defined integer for fast, programmatic identification.
uCalcRetrieves the root uCalc instance that provides the execution context.
VerbatimControls whether variable captures are treated as verbatim blocks, preventing nested matching.
WhitespaceSensitiveControls whether whitespace is treated as a significant token.

⚖️ Comparative Analysis

  • vs. Regular Expressions:
    • Stateful vs. Static: A Regex pattern is typically a static string, often with global flags (/i, /g). To change its behavior, you must recompile it. A uCalc Rule is a dynamic object whose properties (CaseSensitive, Active, etc.) can be toggled at runtime without recompiling the pattern.
    • Context-Awareness: A Rule inherits the token-aware nature of the Transformer. It understands language constructs like quotes and brackets, a level of structural awareness that is difficult and fragile to achieve with pure regex.

Examples

A succinct example that finds all occurrences of a letter but skips the first one.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
t.Text = "a b c a d e a f g";
var ruleA = t.FromTo("a", "[MATCH]");

// Skip the first 'a' that is found
ruleA.StartAfter = 1;

Console.WriteLine(t.Transform());
				
			
a b c [MATCH] d e [MATCH] f g
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   t.Text("a b c a d e a f g");
   auto ruleA = t.FromTo("a", "[MATCH]");

   // Skip the first 'a' that is found
   ruleA.StartAfter(1);

   cout << t.Transform() << endl;
}
				
			
a b c [MATCH] d e [MATCH] f g
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      t.Text = "a b c a d e a f g"
      Dim ruleA = t.FromTo("a", "[MATCH]")
      
      '// Skip the first 'a' that is found
      ruleA.StartAfter = 1
      
      Console.WriteLine(t.Transform())
   End Sub
End Module
				
			
a b c [MATCH] d e [MATCH] f g
Applies `RewindOnChange` to a default rule set to enable complex, multi-rule transformations for a custom `Average` function.
				
					using uCalcSoftware;

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

// Enable rewind for all subsequent rules in this transformer.
t.DefaultRuleSet.SetRewindOnChange(true);

// Define the recursive rules.
t.FromTo("AddUp({x})", "{x}");
t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))");

t.FromTo("ArgCount({x})", "1");
t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))");

// The main rule that combines the others.
t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})");

var expression = "Average(1, 2, 3, 4)";
Console.WriteLine($"Input: {expression}");
Console.WriteLine($"Transform: {t.Transform(expression)}");
Console.WriteLine($"Eval: {uc.Eval(expression)}");
				
			
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.ExpressionTransformer();

   // Enable rewind for all subsequent rules in this transformer.
   t.DefaultRuleSet().SetRewindOnChange(true);

   // Define the recursive rules.
   t.FromTo("AddUp({x})", "{x}");
   t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))");

   t.FromTo("ArgCount({x})", "1");
   t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))");

   // The main rule that combines the others.
   t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})");

   auto expression = "Average(1, 2, 3, 4)";
   cout << "Input: " << expression << endl;
   cout << "Transform: " << t.Transform(expression) << endl;
   cout << "Eval: " << uc.Eval(expression) << endl;
}
				
			
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.ExpressionTransformer
      
      '// Enable rewind for all subsequent rules in this transformer.
      t.DefaultRuleSet.SetRewindOnChange(true)
      
      '// Define the recursive rules.
      t.FromTo("AddUp({x})", "{x}")
      t.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))")
      
      t.FromTo("ArgCount({x})", "1")
      t.FromTo("ArgCount({x}, {y})", "(1 + ArgCount({y}))")
      
      '// The main rule that combines the others.
      t.FromTo("Average({x}, {y})", "AddUp({x}, {y}) / ArgCount({x}, {y})")
      
      Dim expression = "Average(1, 2, 3, 4)"
      Console.WriteLine($"Input: {expression}")
      Console.WriteLine($"Transform: {t.Transform(expression)}")
      Console.WriteLine($"Eval: {uc.Eval(expression)}")
   End Sub
End Module
				
			
Input: Average(1, 2, 3, 4)
Transform: (1 + (2 + (3 + 4))) / (1 + (1 + (1 + 1)))
Eval: 2.5