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.
IndexOf
Method
Product:Â
Class:Â
Retrieves the zero-based index of a match based on its starting character position within the source text.
Syntax
Parameters
Return
int
The zero-based index of the match at the specified position. Returns an invalid index (typically the maximum value for size_t) if no match starts at that exact position.
Remarks
The IndexOf method provides a way to find the index of a match within a Matches collection by using its starting character position as a key.
This is the reverse of methods like StartPosition(), which give you the position for a given index. IndexOf is essential when you have a location in the text and need to identify which match in the collection it corresponds to.
Parameters
startPos: The exact, zero-based character position where the desired match begins in the original source string.nearestIndex(Performance Hint): This optional parameter provides a significant performance optimization for large collections. If you have an estimate of where the match is likely to be, providing anearestIndextells the search algorithm to start looking from that point instead of from the beginning of the list.
💡 Comparative Analysis
vs.
List.IndexOfin C#: Standard library search methods typically find an item by object equality or a predicate.Matches.IndexOfis specialized for its context; it searches by a piece of metadata (the start position) rather than by the match's content or object reference. This is a more direct and efficient way to map a location in a text document back to a structured match.vs. Manual Search: Without this method, you would need to iterate through the entire
Matchescollection and check theStartPositionof each item until you found a match. This is inefficient, especially in large collections.IndexOfleverages optimized internal search algorithms, and thenearestIndexhint further enhances this performance.
Examples
A simple lookup to find the index of the second occurrence of the word 'is'.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "This is a test. It is simple.";
t.Pattern("{@Alpha}");
t.Find();
// The second 'is' starts at character position 19
var index = t.Matches.IndexOf(19);
Console.WriteLine($"The match at character 19 is at index: {index}");
Console.WriteLine($"Match content: '{t.Matches[index].Text}'");
The match at character 19 is at index: 5
Match content: 'is' using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.Text = "This is a test. It is simple."; t.Pattern("{@Alpha}"); t.Find(); // The second 'is' starts at character position 19 var index = t.Matches.IndexOf(19); Console.WriteLine($"The match at character 19 is at index: {index}"); Console.WriteLine($"Match content: '{t.Matches[index].Text}'");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.Text("This is a test. It is simple.");
t.Pattern("{@Alpha}");
t.Find();
// The second 'is' starts at character position 19
auto index = t.Matches().IndexOf(19);
cout << "The match at character 19 is at index: " << index << endl;
cout << "Match content: '" << t.Matches()[index].Text() << "'" << endl;
}
The match at character 19 is at index: 5
Match content: 'is' #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.Text("This is a test. It is simple."); t.Pattern("{@Alpha}"); t.Find(); // The second 'is' starts at character position 19 auto index = t.Matches().IndexOf(19); cout << "The match at character 19 is at index: " << index << endl; cout << "Match content: '" << t.Matches()[index].Text() << "'" << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.Text = "This is a test. It is simple."
t.Pattern("{@Alpha}")
t.Find()
'// The second 'is' starts at character position 19
Dim index = t.Matches.IndexOf(19)
Console.WriteLine($"The match at character 19 is at index: {index}")
Console.WriteLine($"Match content: '{t.Matches(index).Text}'")
End Sub
End Module
The match at character 19 is at index: 5
Match content: 'is' Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.Text = "This is a test. It is simple." t.Pattern("{@Alpha}") t.Find() '// The second 'is' starts at character position 19 Dim index = t.Matches.IndexOf(19) Console.WriteLine($"The match at character 19 is at index: {index}") Console.WriteLine($"Match content: '{t.Matches(index).Text}'") End Sub End Module
Finds the global index of a match that was retrieved from a rule-specific match list.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
var log = "INFO: Task started. ERROR: Connection failed. INFO: Task finished.";
var infoRule = t.Pattern("INFO: {msg}.");
var errorRule = t.Pattern("ERROR: {msg}.");
t.Text = log;
t.Find();
// Get the first match specific to the error rule
var firstErrorMatch = errorRule.Matches[0];
Console.WriteLine($"First error match text: '{firstErrorMatch.Text}'");
// Now, find its index within the global list of all matches
var globalIndex = t.Matches.IndexOf(firstErrorMatch.StartPosition);
Console.WriteLine($"The first error is the match at global index: {globalIndex}");
// Verify by printing the match from the global list
Console.WriteLine($"Global match at that index: '{t.Matches[globalIndex].Text}'");
First error match text: 'ERROR: Connection failed.'
The first error is the match at global index: 1
Global match at that index: 'ERROR: Connection failed.' using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); var log = "INFO: Task started. ERROR: Connection failed. INFO: Task finished."; var infoRule = t.Pattern("INFO: {msg}."); var errorRule = t.Pattern("ERROR: {msg}."); t.Text = log; t.Find(); // Get the first match specific to the error rule var firstErrorMatch = errorRule.Matches[0]; Console.WriteLine($"First error match text: '{firstErrorMatch.Text}'"); // Now, find its index within the global list of all matches var globalIndex = t.Matches.IndexOf(firstErrorMatch.StartPosition); Console.WriteLine($"The first error is the match at global index: {globalIndex}"); // Verify by printing the match from the global list Console.WriteLine($"Global match at that index: '{t.Matches[globalIndex].Text}'");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
auto log = "INFO: Task started. ERROR: Connection failed. INFO: Task finished.";
auto infoRule = t.Pattern("INFO: {msg}.");
auto errorRule = t.Pattern("ERROR: {msg}.");
t.Text(log);
t.Find();
// Get the first match specific to the error rule
auto firstErrorMatch = errorRule.Matches()[0];
cout << "First error match text: '" << firstErrorMatch.Text() << "'" << endl;
// Now, find its index within the global list of all matches
auto globalIndex = t.Matches().IndexOf(firstErrorMatch.StartPosition());
cout << "The first error is the match at global index: " << globalIndex << endl;
// Verify by printing the match from the global list
cout << "Global match at that index: '" << t.Matches()[globalIndex].Text() << "'" << endl;
}
First error match text: 'ERROR: Connection failed.'
The first error is the match at global index: 1
Global match at that index: 'ERROR: Connection failed.' #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); auto log = "INFO: Task started. ERROR: Connection failed. INFO: Task finished."; auto infoRule = t.Pattern("INFO: {msg}."); auto errorRule = t.Pattern("ERROR: {msg}."); t.Text(log); t.Find(); // Get the first match specific to the error rule auto firstErrorMatch = errorRule.Matches()[0]; cout << "First error match text: '" << firstErrorMatch.Text() << "'" << endl; // Now, find its index within the global list of all matches auto globalIndex = t.Matches().IndexOf(firstErrorMatch.StartPosition()); cout << "The first error is the match at global index: " << globalIndex << endl; // Verify by printing the match from the global list cout << "Global match at that index: '" << t.Matches()[globalIndex].Text() << "'" << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
Dim log = "INFO: Task started. ERROR: Connection failed. INFO: Task finished."
Dim infoRule = t.Pattern("INFO: {msg}.")
Dim errorRule = t.Pattern("ERROR: {msg}.")
t.Text = log
t.Find()
'// Get the first match specific to the error rule
Dim firstErrorMatch = errorRule.Matches(0)
Console.WriteLine($"First error match text: '{firstErrorMatch.Text}'")
'// Now, find its index within the global list of all matches
Dim globalIndex = t.Matches.IndexOf(firstErrorMatch.StartPosition)
Console.WriteLine($"The first error is the match at global index: {globalIndex}")
'// Verify by printing the match from the global list
Console.WriteLine($"Global match at that index: '{t.Matches(globalIndex).Text}'")
End Sub
End Module
First error match text: 'ERROR: Connection failed.'
The first error is the match at global index: 1
Global match at that index: 'ERROR: Connection failed.' Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() Dim log = "INFO: Task started. ERROR: Connection failed. INFO: Task finished." Dim infoRule = t.Pattern("INFO: {msg}.") Dim errorRule = t.Pattern("ERROR: {msg}.") t.Text = log t.Find() '// Get the first match specific to the error rule Dim firstErrorMatch = errorRule.Matches(0) Console.WriteLine($"First error match text: '{firstErrorMatch.Text}'") '// Now, find its index within the global list of all matches Dim globalIndex = t.Matches.IndexOf(firstErrorMatch.StartPosition) Console.WriteLine($"The first error is the match at global index: {globalIndex}") '// Verify by printing the match from the global list Console.WriteLine($"Global match at that index: '{t.Matches(globalIndex).Text}'") End Sub End Module
Using IndexOf() in Matches
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.Str("Title
Bold statementTitle B
Other textMy paragraph
");
// ^ ^ ^ ^ ^
// 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
// 0 10 20 30 40 50 60 70 80
// Carrets (^) point to Start locations of the matches
var AnyOtherTag = t.Pattern("<{tag}>{text}{tag}>");
var BoldTag = t.Pattern("{text}");
var H3Tag = t.Pattern("{text}
");
t.Find();
Console.WriteLine("IndexOf StartPos Match");
Console.WriteLine("");
Console.WriteLine("All Matches");
Console.WriteLine("-----------");
foreach(var match in t.Matches) {
Console.WriteLine($"{t.Matches.IndexOf(match.StartPosition)} {match.StartPosition} {match.Text}");
}
Console.WriteLine("");
Console.WriteLine("Bold Matches");
Console.WriteLine("------------");
foreach(var BoldMatch in BoldTag.Matches) {
Console.WriteLine($"{t.Matches.IndexOf(BoldMatch.StartPosition)} {BoldMatch.StartPosition} {BoldMatch.Text}");
}
Console.WriteLine("");
Console.WriteLine("H3 Matches");
Console.WriteLine("----------");
foreach(var H3Match in H3Tag.Matches) {
Console.WriteLine($"{t.Matches.IndexOf(H3Match.StartPosition)} {H3Match.StartPosition} {H3Match.Text}");
}
Console.WriteLine("");
Console.WriteLine("Other Matches");
Console.WriteLine("-------------");
foreach(var AnyOtherMatch in AnyOtherTag.Matches) {
Console.WriteLine($"{t.Matches.IndexOf(AnyOtherMatch.StartPosition)} {AnyOtherMatch.StartPosition} {AnyOtherMatch.Text}");
}
IndexOf StartPos Match
All Matches
-----------
0 0 <h3>Title</h3>
1 14 <b>Bold statement</b>
2 35 <h3>Title B</h3>
3 51 <b>Other text</b>
4 68 <p>My paragraph</p>
Bold Matches
------------
1 14 <b>Bold statement</b>
3 51 <b>Other text</b>
H3 Matches
----------
0 0 <h3>Title</h3>
2 35 <h3>Title B</h3>
Other Matches
-------------
4 68 <p>My paragraph</p> using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.Str("<h3>Title</h3><b>Bold statement</b><h3>Title B</h3><b>Other text</b><p>My paragraph</p>"); // ^ ^ ^ ^ ^ // 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 // 0 10 20 30 40 50 60 70 80 // Carrets (^) point to Start locations of the matches var AnyOtherTag = t.Pattern("<{tag}>{text}</{tag}>"); var BoldTag = t.Pattern("<b>{text}</b>"); var H3Tag = t.Pattern("<h3>{text}</h3>"); t.Find(); Console.WriteLine("IndexOf StartPos Match"); Console.WriteLine(""); Console.WriteLine("All Matches"); Console.WriteLine("-----------"); foreach(var match in t.Matches) { Console.WriteLine($"{t.Matches.IndexOf(match.StartPosition)} {match.StartPosition} {match.Text}"); } Console.WriteLine(""); Console.WriteLine("Bold Matches"); Console.WriteLine("------------"); foreach(var BoldMatch in BoldTag.Matches) { Console.WriteLine($"{t.Matches.IndexOf(BoldMatch.StartPosition)} {BoldMatch.StartPosition} {BoldMatch.Text}"); } Console.WriteLine(""); Console.WriteLine("H3 Matches"); Console.WriteLine("----------"); foreach(var H3Match in H3Tag.Matches) { Console.WriteLine($"{t.Matches.IndexOf(H3Match.StartPosition)} {H3Match.StartPosition} {H3Match.Text}"); } Console.WriteLine(""); Console.WriteLine("Other Matches"); Console.WriteLine("-------------"); foreach(var AnyOtherMatch in AnyOtherTag.Matches) { Console.WriteLine($"{t.Matches.IndexOf(AnyOtherMatch.StartPosition)} {AnyOtherMatch.StartPosition} {AnyOtherMatch.Text}"); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.Str("Title
Bold statementTitle B
Other textMy paragraph
");
// ^ ^ ^ ^ ^
// 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
// 0 10 20 30 40 50 60 70 80
// Carrets (^) point to Start locations of the matches
auto AnyOtherTag = t.Pattern("<{tag}>{text}{tag}>");
auto BoldTag = t.Pattern("{text}");
auto H3Tag = t.Pattern("{text}
");
t.Find();
cout << "IndexOf StartPos Match" << endl;
cout << "" << endl;
cout << "All Matches" << endl;
cout << "-----------" << endl;
for(auto match : t.Matches()) {
cout << t.Matches().IndexOf(match.StartPosition()) << " " << match.StartPosition() << " " << match.Text() << endl;
}
cout << "" << endl;
cout << "Bold Matches" << endl;
cout << "------------" << endl;
for(auto BoldMatch : BoldTag.Matches()) {
cout << t.Matches().IndexOf(BoldMatch.StartPosition()) << " " << BoldMatch.StartPosition() << " " << BoldMatch.Text() << endl;
}
cout << "" << endl;
cout << "H3 Matches" << endl;
cout << "----------" << endl;
for(auto H3Match : H3Tag.Matches()) {
cout << t.Matches().IndexOf(H3Match.StartPosition()) << " " << H3Match.StartPosition() << " " << H3Match.Text() << endl;
}
cout << "" << endl;
cout << "Other Matches" << endl;
cout << "-------------" << endl;
for(auto AnyOtherMatch : AnyOtherTag.Matches()) {
cout << t.Matches().IndexOf(AnyOtherMatch.StartPosition()) << " " << AnyOtherMatch.StartPosition() << " " << AnyOtherMatch.Text() << endl;
}
}
IndexOf StartPos Match
All Matches
-----------
0 0 <h3>Title</h3>
1 14 <b>Bold statement</b>
2 35 <h3>Title B</h3>
3 51 <b>Other text</b>
4 68 <p>My paragraph</p>
Bold Matches
------------
1 14 <b>Bold statement</b>
3 51 <b>Other text</b>
H3 Matches
----------
0 0 <h3>Title</h3>
2 35 <h3>Title B</h3>
Other Matches
-------------
4 68 <p>My paragraph</p> #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.Str("<h3>Title</h3><b>Bold statement</b><h3>Title B</h3><b>Other text</b><p>My paragraph</p>"); // ^ ^ ^ ^ ^ // 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 // 0 10 20 30 40 50 60 70 80 // Carrets (^) point to Start locations of the matches auto AnyOtherTag = t.Pattern("<{tag}>{text}</{tag}>"); auto BoldTag = t.Pattern("<b>{text}</b>"); auto H3Tag = t.Pattern("<h3>{text}</h3>"); t.Find(); cout << "IndexOf StartPos Match" << endl; cout << "" << endl; cout << "All Matches" << endl; cout << "-----------" << endl; for(auto match : t.Matches()) { cout << t.Matches().IndexOf(match.StartPosition()) << " " << match.StartPosition() << " " << match.Text() << endl; } cout << "" << endl; cout << "Bold Matches" << endl; cout << "------------" << endl; for(auto BoldMatch : BoldTag.Matches()) { cout << t.Matches().IndexOf(BoldMatch.StartPosition()) << " " << BoldMatch.StartPosition() << " " << BoldMatch.Text() << endl; } cout << "" << endl; cout << "H3 Matches" << endl; cout << "----------" << endl; for(auto H3Match : H3Tag.Matches()) { cout << t.Matches().IndexOf(H3Match.StartPosition()) << " " << H3Match.StartPosition() << " " << H3Match.Text() << endl; } cout << "" << endl; cout << "Other Matches" << endl; cout << "-------------" << endl; for(auto AnyOtherMatch : AnyOtherTag.Matches()) { cout << t.Matches().IndexOf(AnyOtherMatch.StartPosition()) << " " << AnyOtherMatch.StartPosition() << " " << AnyOtherMatch.Text() << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.Str("Title
Bold statementTitle B
Other textMy paragraph
")
'// ^ ^ ^ ^ ^
'// 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
'// 0 10 20 30 40 50 60 70 80
'// Carrets (^) point to Start locations of the matches
Dim AnyOtherTag = t.Pattern("<{tag}>{text}{tag}>")
Dim BoldTag = t.Pattern("{text}")
Dim H3Tag = t.Pattern("{text}
")
t.Find()
Console.WriteLine("IndexOf StartPos Match")
Console.WriteLine("")
Console.WriteLine("All Matches")
Console.WriteLine("-----------")
For Each match In t.Matches
Console.WriteLine($"{t.Matches.IndexOf(match.StartPosition)} {match.StartPosition} {match.Text}")
Next
Console.WriteLine("")
Console.WriteLine("Bold Matches")
Console.WriteLine("------------")
For Each BoldMatch In BoldTag.Matches
Console.WriteLine($"{t.Matches.IndexOf(BoldMatch.StartPosition)} {BoldMatch.StartPosition} {BoldMatch.Text}")
Next
Console.WriteLine("")
Console.WriteLine("H3 Matches")
Console.WriteLine("----------")
For Each H3Match In H3Tag.Matches
Console.WriteLine($"{t.Matches.IndexOf(H3Match.StartPosition)} {H3Match.StartPosition} {H3Match.Text}")
Next
Console.WriteLine("")
Console.WriteLine("Other Matches")
Console.WriteLine("-------------")
For Each AnyOtherMatch In AnyOtherTag.Matches
Console.WriteLine($"{t.Matches.IndexOf(AnyOtherMatch.StartPosition)} {AnyOtherMatch.StartPosition} {AnyOtherMatch.Text}")
Next
End Sub
End Module
IndexOf StartPos Match
All Matches
-----------
0 0 <h3>Title</h3>
1 14 <b>Bold statement</b>
2 35 <h3>Title B</h3>
3 51 <b>Other text</b>
4 68 <p>My paragraph</p>
Bold Matches
------------
1 14 <b>Bold statement</b>
3 51 <b>Other text</b>
H3 Matches
----------
0 0 <h3>Title</h3>
2 35 <h3>Title B</h3>
Other Matches
-------------
4 68 <p>My paragraph</p> Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.Str("<h3>Title</h3><b>Bold statement</b><h3>Title B</h3><b>Other text</b><p>My paragraph</p>") '// ^ ^ ^ ^ ^ '// 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 '// 0 10 20 30 40 50 60 70 80 '// Carrets (^) point to Start locations of the matches Dim AnyOtherTag = t.Pattern("<{tag}>{text}</{tag}>") Dim BoldTag = t.Pattern("<b>{text}</b>") Dim H3Tag = t.Pattern("<h3>{text}</h3>") t.Find() Console.WriteLine("IndexOf StartPos Match") Console.WriteLine("") Console.WriteLine("All Matches") Console.WriteLine("-----------") For Each match In t.Matches Console.WriteLine($"{t.Matches.IndexOf(match.StartPosition)} {match.StartPosition} {match.Text}") Next Console.WriteLine("") Console.WriteLine("Bold Matches") Console.WriteLine("------------") For Each BoldMatch In BoldTag.Matches Console.WriteLine($"{t.Matches.IndexOf(BoldMatch.StartPosition)} {BoldMatch.StartPosition} {BoldMatch.Text}") Next Console.WriteLine("") Console.WriteLine("H3 Matches") Console.WriteLine("----------") For Each H3Match In H3Tag.Matches Console.WriteLine($"{t.Matches.IndexOf(H3Match.StartPosition)} {H3Match.StartPosition} {H3Match.Text}") Next Console.WriteLine("") Console.WriteLine("Other Matches") Console.WriteLine("-------------") For Each AnyOtherMatch In AnyOtherTag.Matches Console.WriteLine($"{t.Matches.IndexOf(AnyOtherMatch.StartPosition)} {AnyOtherMatch.StartPosition} {AnyOtherMatch.Text}") Next End Sub End Module