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.

StartPosition = [int]

Property

Product: 

Transformer Library

Class: 

Match

Retrieves the zero-based starting character position of the matched substring within the source text.

Remarks

🎯 Position Property: StartPosition

The StartPosition property returns the zero-based character index where an individual match begins within the original source string. It is a fundamental property for understanding the location and context of a match found by a Transformer operation.

This property is accessed on an individual Match object, which is typically retrieved by iterating through a Matches collection returned by Transformer.Matches().

⚙️ How It Works: The Match Coordinate System

StartPosition is part of a coordinate system that precisely defines a match's location and size:

  • StartPosition: The index of the first character of the match.
  • EndPosition: The index of the character immediately after the last character of the match.
  • Length: The total number of characters in the match.

These three properties are always related by the formula:match.Length() == match.EndPosition() - match.StartPosition()

Understanding this relationship is key to programmatically selecting, analyzing, or modifying substrings based on match results.

💡 Comparative Analysis

  • vs. C# Regex Match.Index: The StartPosition property is functionally identical to the Index property on a System.Text.RegularExpressions.Match object in .NET. This design choice makes uCalc's API feel familiar and intuitive to developers accustomed to standard regular expression libraries.

⚠️ For Internal Use: The Setter

This property also has a setter which is not intended for general use. It is used internally by the uCalc wrappers for .NET (C# and VB.NET) to adjust character positions when mapping from the engine's internal UTF-8 string representation to .NET's native UTF-16. Modifying this value directly may lead to inconsistent or incorrect match data.

Examples

A basic example to get the starting index of a single word.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
t.Text = "Hello World";
t.Pattern("World");
t.Find();

var matches = t.Matches;
Console.WriteLine($"Match found at position: {matches[0].StartPosition}");
				
			
Match found at position: 6
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   t.Text("Hello World");
   t.Pattern("World");
   t.Find();

   auto matches = t.Matches();
   cout << "Match found at position: " << matches[0].StartPosition() << endl;
}
				
			
Match found at position: 6
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      t.Text = "Hello World"
      t.Pattern("World")
      t.Find()
      
      Dim matches = t.Matches
      Console.WriteLine($"Match found at position: {matches(0).StartPosition}")
   End Sub
End Module
				
			
Match found at position: 6
Parsing log entries to create a map of error locations within the text.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
t.Text = "[INFO] System boot. [ERROR] Connection failed. [INFO] Retrying...";
t.Pattern("'['ERROR']' {msg}.");
t.Find();

Console.WriteLine($"Found {t.Matches.Count()} error(s):");
foreach(var match in t.Matches) {
   Console.WriteLine($"- '{match.Text}' starts at index {match.StartPosition}");
}
				
			
Found 1 error(s):
- '[ERROR] Connection failed.' starts at index 20
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   t.Text("[INFO] System boot. [ERROR] Connection failed. [INFO] Retrying...");
   t.Pattern("'['ERROR']' {msg}.");
   t.Find();

   cout << "Found " << t.Matches().Count() << " error(s):" << endl;
   for(auto match : t.Matches()) {
      cout << "- '" << match.Text() << "' starts at index " << match.StartPosition() << endl;
   }
}
				
			
Found 1 error(s):
- '[ERROR] Connection failed.' starts at index 20
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      t.Text = "[INFO] System boot. [ERROR] Connection failed. [INFO] Retrying..."
      t.Pattern("'['ERROR']' {msg}.")
      t.Find()
      
      Console.WriteLine($"Found {t.Matches.Count()} error(s):")
      For Each match In t.Matches
         Console.WriteLine($"- '{match.Text}' starts at index {match.StartPosition}")
      Next
   End Sub
End Module
				
			
Found 1 error(s):
- '[ERROR] Connection failed.' starts at index 20
Internal Test: Verifies that StartPosition is correct for multiple, non-contiguous matches.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "a b c a d e a f g";
//        ^       ^       ^
// Pos:   0       6       12
t.Pattern("a");
t.Find();

var matches = t.Matches;
Console.WriteLine($"Match 1 Start: {matches[0].StartPosition}"); // Should be 0
Console.WriteLine($"Match 2 Start: {matches[1].StartPosition}"); // Should be 6
Console.WriteLine($"Match 3 Start: {matches[2].StartPosition}"); // Should be 12
				
			
Match 1 Start: 0
Match 2 Start: 6
Match 3 Start: 12
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   t.Text("a b c a d e a f g");
   //        ^       ^       ^
   // Pos:   0       6       12
   t.Pattern("a");
   t.Find();

   auto matches = t.Matches();
   cout << "Match 1 Start: " << matches[0].StartPosition() << endl; // Should be 0
   cout << "Match 2 Start: " << matches[1].StartPosition() << endl; // Should be 6
   cout << "Match 3 Start: " << matches[2].StartPosition() << endl; // Should be 12
}
				
			
Match 1 Start: 0
Match 2 Start: 6
Match 3 Start: 12
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      t.Text = "a b c a d e a f g"
      '//        ^       ^       ^
      '// Pos:   0       6       12
      t.Pattern("a")
      t.Find()
      
      Dim matches = t.Matches
      Console.WriteLine($"Match 1 Start: {matches(0).StartPosition}") '// Should be 0
      Console.WriteLine($"Match 2 Start: {matches(1).StartPosition}") '// Should be 6
      Console.WriteLine($"Match 3 Start: {matches(2).StartPosition}") '// Should be 12
   End Sub
End Module
				
			
Match 1 Start: 0
Match 2 Start: 6
Match 3 Start: 12
Returns Start and End positions of Transformer matches
				
					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}");
				
			
<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;
}
				
			
<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
				
			
<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
Matches
				
					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("");
}
				
			
<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;
   }
}
				
			
<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
				
			
<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