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.

Multi-Pattern Search

Product: 

Class: 

Simultaneously evaluating multiple distinct search patterns within a single input stream

Remarks

Standard string searching typically looks for one specific sequence of characters at a time. uCalc's Concurrent Patterns allow you to define multiple distinct patterns and search for all of them simultaneously in a single pass through the text.

Precedence & Order Rules:

  1. Text Position Priority: Matches are returned in the order they appear in the source string.
  2. Definition Priority (LIFO): If multiple patterns match starting at the same position (e.g., overlapping anchors), the most recently defined pattern takes precedence.
  3. Fallback Mechanism: If the highest-priority pattern fails to match the subsequent tokens, uCalc automatically backtracks and attempts the next most recently defined pattern that shares the same start anchor.

This architecture makes Concurrent Patterns ideal for tokenizers, lexers, or keyword highlighters where different definitions (like keywords vs. identifiers) might compete for the same text.

Comparative Analysis: Why uCalc?

  • vs. Regex:
    • Parallelism: To search for multiple distinct Regex patterns simultaneously (e.g., a date OR an email OR a specific keyword), you typically have to join them with | into a massive, hard-to-read "super-pattern" or run multiple passes. uCalc lets you add them as separate, clean lines of code that run in one efficient pass.
    • Prioritization: Managing precedence in a giant Regex alternation (PatternA|PatternB) relies strictly on left-to-right ordering and can be tricky to adjust dynamically. uCalc handles precedence via definition order, allowing runtime re-prioritization.
  • vs. Native Code (String.IndexOf):
    • Single Pass: Native searches like IndexOf generally find one string. Finding multiple different strings requires a loop and complex index management to ensure you don't count the same text twice or process overlaps incorrectly. uCalc handles the cursor advancement automatically.

Examples

Searching for two different words in parallel.
				
					using uCalcSoftware;

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

// Define concurrent patterns
t.FromTo("Mango", "[Fruit]");
t.FromTo("Car", "[Vehicle]");

Console.WriteLine(t.Transform("I have a Mango and a Car."));

				
			
I have a [Fruit] and a [Vehicle].
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

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

   // Define concurrent patterns
   t.FromTo("Mango", "[Fruit]");
   t.FromTo("Car", "[Vehicle]");

   cout << t.Transform("I have a Mango and a Car.") << endl;

}
				
			
I have a [Fruit] and a [Vehicle].
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      
      '// Define concurrent patterns
      t.FromTo("Mango", "[Fruit]")
      t.FromTo("Car", "[Vehicle]")
      
      Console.WriteLine(t.Transform("I have a Mango and a Car."))
      
   End Sub
End Module
				
			
I have a [Fruit] and a [Vehicle].
A simple Lexer/Tokenizer that categorizes content into numbers, operators, or keywords.
				
					using uCalcSoftware;

var uc = new uCalc();
// Note how the definition order matters if patterns overlap (though here they are distinct).
var t = uc.NewTransformer();

// Define patterns for a simple math language
t.FromTo("{d: {@Number}}", "[NUM:{d}]");
t.FromTo("{op: + | - | * | / }", "[OP:{op}]");
t.FromTo("print", "[CMD:PRINT]"); // Specific keyword

var code = "print 10 + 20";
Console.WriteLine(t.Transform(code));
				
			
[CMD:PRINT] [NUM:10] [OP:+] [NUM:20]
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // Note how the definition order matters if patterns overlap (though here they are distinct).
   auto t = uc.NewTransformer();

   // Define patterns for a simple math language
   t.FromTo("{d: {@Number}}", "[NUM:{d}]");
   t.FromTo("{op: + | - | * | / }", "[OP:{op}]");
   t.FromTo("print", "[CMD:PRINT]"); // Specific keyword

   auto code = "print 10 + 20";
   cout << t.Transform(code) << endl;
}
				
			
[CMD:PRINT] [NUM:10] [OP:+] [NUM:20]
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// Note how the definition order matters if patterns overlap (though here they are distinct).
      Dim t = uc.NewTransformer()
      
      '// Define patterns for a simple math language
      t.FromTo("{d: {@Number}}", "[NUM:{d}]")
      t.FromTo("{op: + | - | * | / }", "[OP:{op}]")
      t.FromTo("print", "[CMD:PRINT]") '// Specific keyword
      
      Dim code = "print 10 + 20"
      Console.WriteLine(t.Transform(code))
   End Sub
End Module
				
			
[CMD:PRINT] [NUM:10] [OP:+] [NUM:20]
Testing the "Last In, First Out" precedence rule with overlapping anchors.
				
					using uCalcSoftware;

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

// Priority Test: All start with "An"
// 1. Defined first (lowest priority for same start)
t.FromTo("An {item}", "Match1: {item}");

// 2. Defined second
t.FromTo("An {item}.", "Match2: {item}");

// 3. Defined last (Highest priority for same start)
t.FromTo("An orange.", "Match3: orange");

// Input text
var txt = "An orange. An apple. An elephant.";

// "An orange." matches Rule 3 (Specific, defined last)
// "An apple." fails Rule 3, matches Rule 2 (Ending in dot)
// If input is "An elephant" (no dot), it falls back to Rule 1.

Console.WriteLine(t.Transform("An orange."));   // Match3: Orange
Console.WriteLine(t.Transform("An apple."));    // Match2: apple
Console.WriteLine(t.Transform("An elephant"));  // Match1: elephant
				
			
Match3: orange
Match2: apple
Match1: elephant
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

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

   // Priority Test: All start with "An"
   // 1. Defined first (lowest priority for same start)
   t.FromTo("An {item}", "Match1: {item}");

   // 2. Defined second
   t.FromTo("An {item}.", "Match2: {item}");

   // 3. Defined last (Highest priority for same start)
   t.FromTo("An orange.", "Match3: orange");

   // Input text
   auto txt = "An orange. An apple. An elephant.";

   // "An orange." matches Rule 3 (Specific, defined last)
   // "An apple." fails Rule 3, matches Rule 2 (Ending in dot)
   // If input is "An elephant" (no dot), it falls back to Rule 1.

   cout << t.Transform("An orange.") << endl;   // Match3: Orange
   cout << t.Transform("An apple.") << endl;    // Match2: apple
   cout << t.Transform("An elephant") << endl;  // Match1: elephant
}
				
			
Match3: orange
Match2: apple
Match1: elephant
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      
      '// Priority Test: All start with "An"
      '// 1. Defined first (lowest priority for same start)
      t.FromTo("An {item}", "Match1: {item}")
      
      '// 2. Defined second
      t.FromTo("An {item}.", "Match2: {item}")
      
      '// 3. Defined last (Highest priority for same start)
      t.FromTo("An orange.", "Match3: orange")
      
      '// Input text
      Dim txt = "An orange. An apple. An elephant."
      
      '// "An orange." matches Rule 3 (Specific, defined last)
      '// "An apple." fails Rule 3, matches Rule 2 (Ending in dot)
      '// If input is "An elephant" (no dot), it falls back to Rule 1.
      
      Console.WriteLine(t.Transform("An orange."))   '// Match3: Orange
      Console.WriteLine(t.Transform("An apple."))    '// Match2: apple
      Console.WriteLine(t.Transform("An elephant"))  '// Match1: elephant
   End Sub
End Module
				
			
Match3: orange
Match2: apple
Match1: elephant