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.

SkipOver

Method

Product: 

Transformer Library

Class: 

Transformer

Defines a pattern for text that the transformer should ignore, effectively treating it as a 'dead zone' for all other find and replace rules.

Syntax

SkipOver(string)

Parameters

pattern
string
The pattern defining the text to be ignored by all other find/replace rules.

Return

Rule

Rule object

Remarks

🛡️ Excluding Text with SkipOver

The SkipOver method defines a "dead zone" or "no-fly zone" for the transformer. Any text that matches the specified pattern is completely ignored by all other find and replace rules (FromTo and Pattern).

This is the primary mechanism for protecting sections of text from being transformed, with the most common use case being code or markup comments.

🥇 Precedence is Key

It is crucial to understand that SkipOver rules are evaluated before any other type of rule. They have the highest precedence. If a segment of text matches a SkipOver pattern, it is immediately excluded from further processing, and no FromTo or Pattern rules will be tested against it, regardless of their definition order.

SkipOver vs. FromTo(pattern, "{@Self}")

One might think that a rule like t.FromTo("/* {comment} */", "{@Self}") would have the same effect. This is incorrect for two critical reasons:

  1. Precedence: A FromTo rule competes with all other FromTo and Pattern rules based on definition order (LIFO). A SkipOver rule always wins.
  2. Matching: A FromTo rule still creates a Match object that is added to the results collection. A SkipOver match is not recorded and does not appear in the final Matches list.

⚖️ Comparative Analysis

  • vs. Regular Expressions: In standard regex, achieving this "skip" behavior is complex. It often requires negative lookarounds ((?<!...) and (?!...)) or multiple, carefully ordered processing passes. For example, to replace var but not inside a comment, you would need a complicated regex or pre-process the text to remove comments first, then add them back. uCalc's SkipOver makes this a single, declarative, and highly readable step.

Conclusion: Use SkipOver for any content that should be completely invisible to the rest of your transformation logic.

Examples

A succinct example showing how `SkipOver` creates 'dead zones' where other rules are not applied.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
t.Text = "transform this but (not this) and this";

// A rule to replace the word 'this'
t.FromTo("this", "THAT");

// A rule to ignore any content inside parentheses
t.SkipOver("({content})");

// The 'this' inside the parentheses is protected by the SkipOver rule
Console.WriteLine(t.Transform());
				
			
transform THAT but (not this) and THAT
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   t.Text("transform this but (not this) and this");

   // A rule to replace the word 'this'
   t.FromTo("this", "THAT");

   // A rule to ignore any content inside parentheses
   t.SkipOver("({content})");

   // The 'this' inside the parentheses is protected by the SkipOver rule
   cout << t.Transform() << endl;
}
				
			
transform THAT but (not this) and THAT
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      t.Text = "transform this but (not this) and this"
      
      '// A rule to replace the word 'this'
      t.FromTo("this", "THAT")
      
      '// A rule to ignore any content inside parentheses
      t.SkipOver("({content})")
      
      '// The 'this' inside the parentheses is protected by the SkipOver rule
      Console.WriteLine(t.Transform())
   End Sub
End Module
				
			
transform THAT but (not this) and THAT
A practical, real-world example of using `SkipOver` to ignore HTML comments while transforming other parts of the document.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
// Disable statement sensitivity to handle multi-line content
t.DefaultRuleSet.StatementSensitive = false;

var htmlContent =
"""

<nav>
  <li><a href="#intro">Intro</a></li>
  <!-- <li><a href="#contact">Contact</a></li> -->
  <li><a href="#about">About</a></li>
</nav>

""";
t.Text = htmlContent;

// A rule to find all list items
t.Pattern("<li>{item}</li>");

// A rule to skip over HTML comments
t.SkipOver("<!-- {comment} -->");

t.Find();
Console.WriteLine("--- Found List Items ---");
Console.WriteLine(t.Matches.Text);
				
			
--- Found List Items ---
<li><a href="#intro">Intro</a></li>
<li><a href="#about">About</a></li>
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   // Disable statement sensitivity to handle multi-line content
   t.DefaultRuleSet().StatementSensitive(false);

   auto htmlContent =
   R"(
<nav>
  <li><a href="#intro">Intro</a></li>
  <!-- <li><a href="#contact">Contact</a></li> -->
  <li><a href="#about">About</a></li>
</nav>
)";
   t.Text(htmlContent);

   // A rule to find all list items
   t.Pattern("<li>{item}</li>");

   // A rule to skip over HTML comments
   t.SkipOver("<!-- {comment} -->");

   t.Find();
   cout << "--- Found List Items ---" << endl;
   cout << t.Matches().Text() << endl;
}
				
			
--- Found List Items ---
<li><a href="#intro">Intro</a></li>
<li><a href="#about">About</a></li>
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      '// Disable statement sensitivity to handle multi-line content
      t.DefaultRuleSet.StatementSensitive = false
      
      Dim htmlContent =
      "
<nav>
  <li><a href=""#intro"">Intro</a></li>
  <!-- <li><a href=""#contact"">Contact</a></li> -->
  <li><a href=""#about"">About</a></li>
</nav>
"
      t.Text = htmlContent
      
      '// A rule to find all list items
      t.Pattern("<li>{item}</li>")
      
      '// A rule to skip over HTML comments
      t.SkipOver("<!-- {comment} -->")
      
      t.Find()
      Console.WriteLine("--- Found List Items ---")
      Console.WriteLine(t.Matches.Text)
   End Sub
End Module
				
			
--- Found List Items ---
<li><a href="#intro">Intro</a></li>
<li><a href="#about">About</a></li>
SkipOver(), Str(), Implicit Str()
				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
var txt = "a b c (a b c a b c) a b c";
t.FromTo("a", "AA");

// You can either set the string before or pass it to Transform()
t.Str(txt);
Console.WriteLine(t.Transform().Text);

t.SkipOver("({text})");
Console.WriteLine(t.Transform(txt)); // Implicit Text property
				
			
AA b c (AA b c AA b c) AA b c
AA b c (a b c a b c) AA b c
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   auto txt = "a b c (a b c a b c) a b c";
   t.FromTo("a", "AA");

   // You can either set the string before or pass it to Transform()
   t.Str(txt);
   cout << t.Transform().Text() << endl;

   t.SkipOver("({text})");
   cout << t.Transform(txt) << endl; // Implicit Text property
}
				
			
AA b c (AA b c AA b c) AA b c
AA b c (a b c a b c) AA b c
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      Dim txt = "a b c (a b c a b c) a b c"
      t.FromTo("a", "AA")
      
      '// You can either set the string before or pass it to Transform()
      t.Str(txt)
      Console.WriteLine(t.Transform().Text)
      
      t.SkipOver("({text})")
      Console.WriteLine(t.Transform(txt)) '// Implicit Text property
   End Sub
End Module
				
			
AA b c (AA b c AA b c) AA b c
AA b c (a b c a b c) AA b c
How to find matched patterns while skipping commented text using SkipOver().
				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
t.Str("int result = (x + 3) * 2 - (y - 7 / z) * (5 ^ a + 10); /* (x + y) */");

// Capture standard blocks surrounded by parentheses
t.Pattern("({expr})");

// Instruct the transformer to ignore any text inside C-style block comments.
// This prevents the commented "(x + y)" from being falsely counted as a match.
t.SkipOver("/* {etc} */"); // commented text between /* */ is skipped

t.Find();
Console.WriteLine(t.Matches.Count());
				
			
3
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   t.Str("int result = (x + 3) * 2 - (y - 7 / z) * (5 ^ a + 10); /* (x + y) */");

   // Capture standard blocks surrounded by parentheses
   t.Pattern("({expr})");

   // Instruct the transformer to ignore any text inside C-style block comments.
   // This prevents the commented "(x + y)" from being falsely counted as a match.
   t.SkipOver("/* {etc} */"); // commented text between /* */ is skipped

   t.Find();
   cout << t.Matches().Count() << endl;
}
				
			
3
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      t.Str("int result = (x + 3) * 2 - (y - 7 / z) * (5 ^ a + 10); /* (x + y) */")
      
      '// Capture standard blocks surrounded by parentheses
      t.Pattern("({expr})")
      
      '// Instruct the transformer to ignore any text inside C-style block comments.
      '// This prevents the commented "(x + y)" from being falsely counted as a match.
      t.SkipOver("/* {etc} */") '// commented text between /* */ is skipped
      
      t.Find()
      Console.WriteLine(t.Matches.Count())
   End Sub
End Module
				
			
3
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
Using SkipOver() to ignore XML-style comments
				
					using uCalcSoftware;

var uc = new uCalc();
// StatementSensitive() is set to false so that ";" and newline are not treated as special

var t = uc.NewTransformer();
Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}");
Console.WriteLine("Setting StatementSensitive to False");

t.DefaultRuleSet.StatementSensitive = false; // so that newline does not behave as a statement separator

Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}");
Console.WriteLine("");

var Content =
"""

<nav aria-label="Main navigation">
  <ul>
    <li><a href="#intro">Intro</a></li>
    <li><a href="#examples">Examples</a></li>
    <!-- <li><a href="#contact">Contact</a></li> -->
  </ul>
</nav>

<!-- 
<h2>Ingredients</h2>
<ul>
  <li>3 cups flour</li>
  <li>1.5 cups water</li>
  <li>1 tsp salt</li>
</ul>
-->

<nav aria-label="Chapter navigation">
    <ul>
      <li><a href="#one">One</a></li>
      <li><a href="#two">Two</a></li>
      <li><a href="#three">Three</a></li>
    </ul>
</nav>

""";

t.Str(Content);
var Pattern = t.Pattern("<li>{item}</li>");
t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

Console.WriteLine("<!-- Skip over commented lines -->");
Console.WriteLine("----------------------------------");
t.SkipOver("<!-- {comment} -->");
t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

				
			
StatementSensitive: True
Setting StatementSensitive to False
StatementSensitive: False

<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#contact">Contact</a></li>
<li>3 cups flour</li>
<li>1.5 cups water</li>
<li>1 tsp salt</li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>

<!-- Skip over commented lines -->
----------------------------------
<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

#define tf(IsTrue) ((IsTrue) ? "True" : "False")

int main() {
   uCalc uc;
   // StatementSensitive() is set to false so that ";" and newline are not treated as special

   auto t = uc.NewTransformer();
   cout << "StatementSensitive: " << tf(t.DefaultRuleSet().StatementSensitive()) << endl;
   cout << "Setting StatementSensitive to False" << endl;

   t.DefaultRuleSet().StatementSensitive(false); // so that newline does not behave as a statement separator

   cout << "StatementSensitive: " << tf(t.DefaultRuleSet().StatementSensitive()) << endl;
   cout << "" << endl;

   auto Content =
   R"(
<nav aria-label="Main navigation">
  <ul>
    <li><a href="#intro">Intro</a></li>
    <li><a href="#examples">Examples</a></li>
    <!-- <li><a href="#contact">Contact</a></li> -->
  </ul>
</nav>

<!-- 
<h2>Ingredients</h2>
<ul>
  <li>3 cups flour</li>
  <li>1.5 cups water</li>
  <li>1 tsp salt</li>
</ul>
-->

<nav aria-label="Chapter navigation">
    <ul>
      <li><a href="#one">One</a></li>
      <li><a href="#two">Two</a></li>
      <li><a href="#three">Three</a></li>
    </ul>
</nav>
)";

   t.Str(Content);
   auto Pattern = t.Pattern("<li>{item}</li>");
   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

   cout << "<!-- Skip over commented lines -->" << endl;
   cout << "----------------------------------" << endl;
   t.SkipOver("<!-- {comment} -->");
   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

}
				
			
StatementSensitive: True
Setting StatementSensitive to False
StatementSensitive: False

<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#contact">Contact</a></li>
<li>3 cups flour</li>
<li>1.5 cups water</li>
<li>1 tsp salt</li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>

<!-- Skip over commented lines -->
----------------------------------
<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// StatementSensitive() is set to false so that ";" and newline are not treated as special
      
      Dim t = uc.NewTransformer()
      Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}")
      Console.WriteLine("Setting StatementSensitive to False")
      
      t.DefaultRuleSet.StatementSensitive = false '// so that newline does not behave as a statement separator
      
      Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}")
      Console.WriteLine("")
      
      Dim Content =
      "
<nav aria-label=""Main navigation"">
  <ul>
    <li><a href=""#intro"">Intro</a></li>
    <li><a href=""#examples"">Examples</a></li>
    <!-- <li><a href=""#contact"">Contact</a></li> -->
  </ul>
</nav>

<!-- 
<h2>Ingredients</h2>
<ul>
  <li>3 cups flour</li>
  <li>1.5 cups water</li>
  <li>1 tsp salt</li>
</ul>
-->

<nav aria-label=""Chapter navigation"">
    <ul>
      <li><a href=""#one"">One</a></li>
      <li><a href=""#two"">Two</a></li>
      <li><a href=""#three"">Three</a></li>
    </ul>
</nav>
"
      
      t.Str(Content)
      Dim Pattern = t.Pattern("<li>{item}</li>")
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
      Console.WriteLine("<!-- Skip over commented lines -->")
      Console.WriteLine("----------------------------------")
      t.SkipOver("<!-- {comment} -->")
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
   End Sub
End Module
				
			
StatementSensitive: True
Setting StatementSensitive to False
StatementSensitive: False

<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#contact">Contact</a></li>
<li>3 cups flour</li>
<li>1.5 cups water</li>
<li>1 tsp salt</li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>

<!-- Skip over commented lines -->
----------------------------------
<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>