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.

StartPosition = [int]

Property

Product: 

Class: 

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.

ID: 829

				
					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.

ID: 830

				
					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.

ID: 831

				
					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

ID: 111

				
					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

ID: 114

				
					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