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.
Product:
Class:
Executes a search operation on the current text using all defined pattern rules, populating the internal collection of matches.
The current Transformer object
The Find() method is the primary function for executing a read-only search operation. It processes the text currently held by the Transformer against all active rules, populating an internal collection of matches without modifying the text itself.
Find(), you must define what to search for using methods like Pattern(), FromTo(), and SkipOver().Find() to run the search engine. The transformer scans the text, and every time a segment matches a rule, a Match object is created and stored internally.All active rules are evaluated concurrently in a single pass. If multiple patterns could match at the same location, the most recently defined rule takes precedence. This LIFO (Last-In, First-Out) ordering is crucial for managing overlapping patterns.
Find() vs. Transform() vs. Filter()These three methods trigger the same core matching engine but produce different outcomes:
| Method | Effect on Text | Primary Use Case |
|---|---|---|
Find() | 🔵 None. The text is not modified. | Pure search and analysis. Find locations without altering the source. |
Transform() | 🟠 Modified. Matched text is replaced. | Search-and-replace operations. |
Filter() | 🔴 Replaced. Text is replaced with a concatenation of all matches. | Extracting all matching segments from a larger document. |
Find() offers significant advantages over traditional string search methods.
vs. Regular Expressions (Regex.Matches):
() or quotes "". uCalc's Find() operates on tokens, so it inherently understands these structures, preventing incorrect matches inside string literals or across mismatched brackets.(pattern1|pattern2|...)). With uCalc, you define each pattern with a separate, clear Pattern() call, and Find() executes them all concurrently.vs. string.IndexOf:
IndexOf finds the first occurrence of a single, literal substring. Find() locates multiple occurrences of complex, token-aware patterns with variables, alternations, and other advanced logic.ID: 1065
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
t.Text = "apple banana apple cherry apple";
t.Pattern("apple");
t.Find();
Console.WriteLine($"Found {t.Matches.Count()} occurrences of 'apple'.");
Found 3 occurrences of 'apple'. using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); t.Text = "apple banana apple cherry apple"; t.Pattern("apple"); t.Find(); Console.WriteLine($"Found {t.Matches.Count()} occurrences of 'apple'.");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
t.Text("apple banana apple cherry apple");
t.Pattern("apple");
t.Find();
cout << "Found " << t.Matches().Count() << " occurrences of 'apple'." << endl;
}
Found 3 occurrences of 'apple'. #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; t.Text("apple banana apple cherry apple"); t.Pattern("apple"); t.Find(); cout << "Found " << t.Matches().Count() << " occurrences of 'apple'." << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
t.Text = "apple banana apple cherry apple"
t.Pattern("apple")
t.Find()
Console.WriteLine($"Found {t.Matches.Count()} occurrences of 'apple'.")
End Sub
End Module
Found 3 occurrences of 'apple'. Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() t.Text = "apple banana apple cherry apple" t.Pattern("apple") t.Find() Console.WriteLine($"Found {t.Matches.Count()} occurrences of 'apple'.") End Sub End Module
ID: 1066
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
var logText = "INFO: System start. WARN: Low disk. ERROR: DB connection failed.";
t.Text = logText;
// Define rules for different log levels
var errorRule = t.Pattern("ERROR: {msg}.");
var warnRule = t.Pattern("WARN: {msg}.");
t.Find();
Console.WriteLine($"Total issues found: {t.Matches.Count()}");
Console.WriteLine("--- Error Matches ---");
Console.WriteLine(errorRule.Matches.Text);
Console.WriteLine("--- Warning Matches ---");
Console.WriteLine(warnRule.Matches.Text);
Total issues found: 2
--- Error Matches ---
ERROR: DB connection failed.
--- Warning Matches ---
WARN: Low disk. using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); var logText = "INFO: System start. WARN: Low disk. ERROR: DB connection failed."; t.Text = logText; // Define rules for different log levels var errorRule = t.Pattern("ERROR: {msg}."); var warnRule = t.Pattern("WARN: {msg}."); t.Find(); Console.WriteLine($"Total issues found: {t.Matches.Count()}"); Console.WriteLine("--- Error Matches ---"); Console.WriteLine(errorRule.Matches.Text); Console.WriteLine("--- Warning Matches ---"); Console.WriteLine(warnRule.Matches.Text);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
auto logText = "INFO: System start. WARN: Low disk. ERROR: DB connection failed.";
t.Text(logText);
// Define rules for different log levels
auto errorRule = t.Pattern("ERROR: {msg}.");
auto warnRule = t.Pattern("WARN: {msg}.");
t.Find();
cout << "Total issues found: " << t.Matches().Count() << endl;
cout << "--- Error Matches ---" << endl;
cout << errorRule.Matches().Text() << endl;
cout << "--- Warning Matches ---" << endl;
cout << warnRule.Matches().Text() << endl;
}
Total issues found: 2
--- Error Matches ---
ERROR: DB connection failed.
--- Warning Matches ---
WARN: Low disk. #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; auto logText = "INFO: System start. WARN: Low disk. ERROR: DB connection failed."; t.Text(logText); // Define rules for different log levels auto errorRule = t.Pattern("ERROR: {msg}."); auto warnRule = t.Pattern("WARN: {msg}."); t.Find(); cout << "Total issues found: " << t.Matches().Count() << endl; cout << "--- Error Matches ---" << endl; cout << errorRule.Matches().Text() << endl; cout << "--- Warning Matches ---" << endl; cout << warnRule.Matches().Text() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
Dim logText = "INFO: System start. WARN: Low disk. ERROR: DB connection failed."
t.Text = logText
'// Define rules for different log levels
Dim errorRule = t.Pattern("ERROR: {msg}.")
Dim warnRule = t.Pattern("WARN: {msg}.")
t.Find()
Console.WriteLine($"Total issues found: {t.Matches.Count()}")
Console.WriteLine("--- Error Matches ---")
Console.WriteLine(errorRule.Matches.Text)
Console.WriteLine("--- Warning Matches ---")
Console.WriteLine(warnRule.Matches.Text)
End Sub
End Module
Total issues found: 2
--- Error Matches ---
ERROR: DB connection failed.
--- Warning Matches ---
WARN: Low disk. Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() Dim logText = "INFO: System start. WARN: Low disk. ERROR: DB connection failed." t.Text = logText '// Define rules for different log levels Dim errorRule = t.Pattern("ERROR: {msg}.") Dim warnRule = t.Pattern("WARN: {msg}.") t.Find() Console.WriteLine($"Total issues found: {t.Matches.Count()}") Console.WriteLine("--- Error Matches ---") Console.WriteLine(errorRule.Matches.Text) Console.WriteLine("--- Warning Matches ---") Console.WriteLine(warnRule.Matches.Text) End Sub End Module
ID: 1067
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
t.Text = "The apple is an apple.";
// Overlapping patterns. The longer one is defined last, so it gets precedence.
t.Pattern("apple");
t.Pattern("an apple");
Console.WriteLine("--- First Find ---");
t.Find();
// The first 'apple' matches the first rule.
// The 'an apple' matches the second (higher precedence) rule.
Console.WriteLine(t.Matches.Text);
// Re-running find should produce the exact same result
Console.WriteLine("--- Second Find (no change) ---");
t.Find();
Console.WriteLine(t.Matches.Text);
--- First Find ---
apple
an apple
--- Second Find (no change) ---
apple
an apple using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); t.Text = "The apple is an apple."; // Overlapping patterns. The longer one is defined last, so it gets precedence. t.Pattern("apple"); t.Pattern("an apple"); Console.WriteLine("--- First Find ---"); t.Find(); // The first 'apple' matches the first rule. // The 'an apple' matches the second (higher precedence) rule. Console.WriteLine(t.Matches.Text); // Re-running find should produce the exact same result Console.WriteLine("--- Second Find (no change) ---"); t.Find(); Console.WriteLine(t.Matches.Text);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
t.Text("The apple is an apple.");
// Overlapping patterns. The longer one is defined last, so it gets precedence.
t.Pattern("apple");
t.Pattern("an apple");
cout << "--- First Find ---" << endl;
t.Find();
// The first 'apple' matches the first rule.
// The 'an apple' matches the second (higher precedence) rule.
cout << t.Matches().Text() << endl;
// Re-running find should produce the exact same result
cout << "--- Second Find (no change) ---" << endl;
t.Find();
cout << t.Matches().Text() << endl;
}
--- First Find ---
apple
an apple
--- Second Find (no change) ---
apple
an apple #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; t.Text("The apple is an apple."); // Overlapping patterns. The longer one is defined last, so it gets precedence. t.Pattern("apple"); t.Pattern("an apple"); cout << "--- First Find ---" << endl; t.Find(); // The first 'apple' matches the first rule. // The 'an apple' matches the second (higher precedence) rule. cout << t.Matches().Text() << endl; // Re-running find should produce the exact same result cout << "--- Second Find (no change) ---" << endl; t.Find(); cout << t.Matches().Text() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
t.Text = "The apple is an apple."
'// Overlapping patterns. The longer one is defined last, so it gets precedence.
t.Pattern("apple")
t.Pattern("an apple")
Console.WriteLine("--- First Find ---")
t.Find()
'// The first 'apple' matches the first rule.
'// The 'an apple' matches the second (higher precedence) rule.
Console.WriteLine(t.Matches.Text)
'// Re-running find should produce the exact same result
Console.WriteLine("--- Second Find (no change) ---")
t.Find()
Console.WriteLine(t.Matches.Text)
End Sub
End Module
--- First Find ---
apple
an apple
--- Second Find (no change) ---
apple
an apple Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() t.Text = "The apple is an apple." '// Overlapping patterns. The longer one is defined last, so it gets precedence. t.Pattern("apple") t.Pattern("an apple") Console.WriteLine("--- First Find ---") t.Find() '// The first 'apple' matches the first rule. '// The 'an apple' matches the second (higher precedence) rule. Console.WriteLine(t.Matches.Text) '// Re-running find should produce the exact same result Console.WriteLine("--- Second Find (no change) ---") t.Find() Console.WriteLine(t.Matches.Text) End Sub End Module
ID: 111
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "
First
Blah Blah
Testing
Second
";
// ^ ^ ^ ^
// 012345678901234567890123456789012345678901234567890123456789
// 0 10 20 30 40 50
// Carrets (^) point to Start and End locations of the matches
Console.WriteLine(t.Text);
Console.WriteLine("");
t.Pattern("<{tag}>{etc}{tag}>");
t.Find();
var Matches = t.Matches;
Console.WriteLine(Matches[0].Text);
Console.WriteLine($"Start pos: {Matches[0].StartPosition}");
Console.WriteLine($"End pos: {Matches[0].EndPosition}");
Console.WriteLine($"Length: {Matches[0].Length}");
Console.WriteLine("");
Console.WriteLine(Matches[1].Text);
Console.WriteLine($"Start pos: {Matches[1].StartPosition}");
Console.WriteLine($"End pos: {Matches[1].EndPosition}");
Console.WriteLine($"Length: {Matches[1].Length}");
<br><h1>First</h1>Blah Blah<br>Testing<br><h2>Second</h2>
<h1>First</h1>
Start pos: 4
End pos: 18
Length: 14
<h2>Second</h2>
Start pos: 42
End pos: 57
Length: 15 using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.Text = "<br><h1>First</h1>Blah Blah<br>Testing<br><h2>Second</h2>"; // ^ ^ ^ ^ // 012345678901234567890123456789012345678901234567890123456789 // 0 10 20 30 40 50 // Carrets (^) point to Start and End locations of the matches Console.WriteLine(t.Text); Console.WriteLine(""); t.Pattern("<{tag}>{etc}</{tag}>"); t.Find(); var Matches = t.Matches; Console.WriteLine(Matches[0].Text); Console.WriteLine($"Start pos: {Matches[0].StartPosition}"); Console.WriteLine($"End pos: {Matches[0].EndPosition}"); Console.WriteLine($"Length: {Matches[0].Length}"); Console.WriteLine(""); Console.WriteLine(Matches[1].Text); Console.WriteLine($"Start pos: {Matches[1].StartPosition}"); Console.WriteLine($"End pos: {Matches[1].EndPosition}"); Console.WriteLine($"Length: {Matches[1].Length}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.Text("
First
Blah Blah
Testing
Second
");
// ^ ^ ^ ^
// 012345678901234567890123456789012345678901234567890123456789
// 0 10 20 30 40 50
// Carrets (^) point to Start and End locations of the matches
cout << t.Text() << endl;
cout << "" << endl;
t.Pattern("<{tag}>{etc}{tag}>");
t.Find();
auto Matches = t.Matches();
cout << Matches[0].Text() << endl;
cout << "Start pos: " << Matches[0].StartPosition() << endl;
cout << "End pos: " << Matches[0].EndPosition() << endl;
cout << "Length: " << Matches[0].Length() << endl;
cout << "" << endl;
cout << Matches[1].Text() << endl;
cout << "Start pos: " << Matches[1].StartPosition() << endl;
cout << "End pos: " << Matches[1].EndPosition() << endl;
cout << "Length: " << Matches[1].Length() << endl;
}
<br><h1>First</h1>Blah Blah<br>Testing<br><h2>Second</h2>
<h1>First</h1>
Start pos: 4
End pos: 18
Length: 14
<h2>Second</h2>
Start pos: 42
End pos: 57
Length: 15 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.Text("<br><h1>First</h1>Blah Blah<br>Testing<br><h2>Second</h2>"); // ^ ^ ^ ^ // 012345678901234567890123456789012345678901234567890123456789 // 0 10 20 30 40 50 // Carrets (^) point to Start and End locations of the matches cout << t.Text() << endl; cout << "" << endl; t.Pattern("<{tag}>{etc}</{tag}>"); t.Find(); auto Matches = t.Matches(); cout << Matches[0].Text() << endl; cout << "Start pos: " << Matches[0].StartPosition() << endl; cout << "End pos: " << Matches[0].EndPosition() << endl; cout << "Length: " << Matches[0].Length() << endl; cout << "" << endl; cout << Matches[1].Text() << endl; cout << "Start pos: " << Matches[1].StartPosition() << endl; cout << "End pos: " << Matches[1].EndPosition() << endl; cout << "Length: " << Matches[1].Length() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.Text = "
First
Blah Blah
Testing
Second
"
'// ^ ^ ^ ^
'// 012345678901234567890123456789012345678901234567890123456789
'// 0 10 20 30 40 50
'// Carrets (^) point to Start and End locations of the matches
Console.WriteLine(t.Text)
Console.WriteLine("")
t.Pattern("<{tag}>{etc}{tag}>")
t.Find()
Dim Matches = t.Matches
Console.WriteLine(Matches(0).Text)
Console.WriteLine($"Start pos: {Matches(0).StartPosition}")
Console.WriteLine($"End pos: {Matches(0).EndPosition}")
Console.WriteLine($"Length: {Matches(0).Length}")
Console.WriteLine("")
Console.WriteLine(Matches(1).Text)
Console.WriteLine($"Start pos: {Matches(1).StartPosition}")
Console.WriteLine($"End pos: {Matches(1).EndPosition}")
Console.WriteLine($"Length: {Matches(1).Length}")
End Sub
End Module
<br><h1>First</h1>Blah Blah<br>Testing<br><h2>Second</h2>
<h1>First</h1>
Start pos: 4
End pos: 18
Length: 14
<h2>Second</h2>
Start pos: 42
End pos: 57
Length: 15 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.Text = "<br><h1>First</h1>Blah Blah<br>Testing<br><h2>Second</h2>" '// ^ ^ ^ ^ '// 012345678901234567890123456789012345678901234567890123456789 '// 0 10 20 30 40 50 '// Carrets (^) point to Start and End locations of the matches Console.WriteLine(t.Text) Console.WriteLine("") t.Pattern("<{tag}>{etc}</{tag}>") t.Find() Dim Matches = t.Matches Console.WriteLine(Matches(0).Text) Console.WriteLine($"Start pos: {Matches(0).StartPosition}") Console.WriteLine($"End pos: {Matches(0).EndPosition}") Console.WriteLine($"Length: {Matches(0).Length}") Console.WriteLine("") Console.WriteLine(Matches(1).Text) Console.WriteLine($"Start pos: {Matches(1).StartPosition}") Console.WriteLine($"End pos: {Matches(1).EndPosition}") Console.WriteLine($"Length: {Matches(1).Length}") End Sub End Module
ID: 114
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "Title
Bold statementOther textMy paragraph
";
// 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
// 0 10 20 30 40 50 60 70 80 90
// ^ ^ ^ ^ ^
// Carrets (^) represent starting and ending point of the matches
t.Pattern("<{tag}>{text}{tag}>");
t.Pattern("{text}");
t.Pattern("{text}
");
t.SkipOver("");
t.Find();
foreach(var match in t.Matches) {
Console.WriteLine(match.Text);
Console.WriteLine($"Start pos: {match.StartPosition}");
Console.WriteLine($"End pos: {match.EndPosition}");
Console.WriteLine($"Length: {match.Length}");
Console.WriteLine("");
}
<h3>Title</h3>
Start pos: 0
End pos: 14
Length: 14
<b>Bold statement</b>
Start pos: 14
End pos: 35
Length: 21
<b>Other text</b>
Start pos: 58
End pos: 75
Length: 17
<p>My paragraph</p>
Start pos: 75
End pos: 94
Length: 19 using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.Text = "<h3>Title</h3><b>Bold statement</b><!--<h3>Title B</h3>--><b>Other text</b><p>My paragraph</p>"; // 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 // 0 10 20 30 40 50 60 70 80 90 // ^ ^ ^ ^ ^ // Carrets (^) represent starting and ending point of the matches t.Pattern("<{tag}>{text}</{tag}>"); t.Pattern("<b>{text}</b>"); t.Pattern("<h3>{text}</h3>"); t.SkipOver("<!--{text}-->"); t.Find(); foreach(var match in t.Matches) { Console.WriteLine(match.Text); Console.WriteLine($"Start pos: {match.StartPosition}"); Console.WriteLine($"End pos: {match.EndPosition}"); Console.WriteLine($"Length: {match.Length}"); Console.WriteLine(""); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.Text("Title
Bold statementOther textMy paragraph
");
// 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
// 0 10 20 30 40 50 60 70 80 90
// ^ ^ ^ ^ ^
// Carrets (^) represent starting and ending point of the matches
t.Pattern("<{tag}>{text}{tag}>");
t.Pattern("{text}");
t.Pattern("{text}
");
t.SkipOver("");
t.Find();
for(auto match : t.Matches()) {
cout << match.Text() << endl;
cout << "Start pos: " << match.StartPosition() << endl;
cout << "End pos: " << match.EndPosition() << endl;
cout << "Length: " << match.Length() << endl;
cout << "" << endl;
}
}
<h3>Title</h3>
Start pos: 0
End pos: 14
Length: 14
<b>Bold statement</b>
Start pos: 14
End pos: 35
Length: 21
<b>Other text</b>
Start pos: 58
End pos: 75
Length: 17
<p>My paragraph</p>
Start pos: 75
End pos: 94
Length: 19 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.Text("<h3>Title</h3><b>Bold statement</b><!--<h3>Title B</h3>--><b>Other text</b><p>My paragraph</p>"); // 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 // 0 10 20 30 40 50 60 70 80 90 // ^ ^ ^ ^ ^ // Carrets (^) represent starting and ending point of the matches t.Pattern("<{tag}>{text}</{tag}>"); t.Pattern("<b>{text}</b>"); t.Pattern("<h3>{text}</h3>"); t.SkipOver("<!--{text}-->"); t.Find(); for(auto match : t.Matches()) { cout << match.Text() << endl; cout << "Start pos: " << match.StartPosition() << endl; cout << "End pos: " << match.EndPosition() << endl; cout << "Length: " << match.Length() << endl; cout << "" << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.Text = "Title
Bold statementOther textMy paragraph
"
'// 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
'// 0 10 20 30 40 50 60 70 80 90
'// ^ ^ ^ ^ ^
'// Carrets (^) represent starting and ending point of the matches
t.Pattern("<{tag}>{text}{tag}>")
t.Pattern("{text}")
t.Pattern("{text}
")
t.SkipOver("")
t.Find()
For Each match In t.Matches
Console.WriteLine(match.Text)
Console.WriteLine($"Start pos: {match.StartPosition}")
Console.WriteLine($"End pos: {match.EndPosition}")
Console.WriteLine($"Length: {match.Length}")
Console.WriteLine("")
Next
End Sub
End Module
<h3>Title</h3>
Start pos: 0
End pos: 14
Length: 14
<b>Bold statement</b>
Start pos: 14
End pos: 35
Length: 21
<b>Other text</b>
Start pos: 58
End pos: 75
Length: 17
<p>My paragraph</p>
Start pos: 75
End pos: 94
Length: 19 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.Text = "<h3>Title</h3><b>Bold statement</b><!--<h3>Title B</h3>--><b>Other text</b><p>My paragraph</p>" '// 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 '// 0 10 20 30 40 50 60 70 80 90 '// ^ ^ ^ ^ ^ '// Carrets (^) represent starting and ending point of the matches t.Pattern("<{tag}>{text}</{tag}>") t.Pattern("<b>{text}</b>") t.Pattern("<h3>{text}</h3>") t.SkipOver("<!--{text}-->") t.Find() For Each match In t.Matches Console.WriteLine(match.Text) Console.WriteLine($"Start pos: {match.StartPosition}") Console.WriteLine($"End pos: {match.EndPosition}") Console.WriteLine($"Length: {match.Length}") Console.WriteLine("") Next End Sub End Module