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.

BracketSensitive = [bool]

Property

Product: 

Transformer Library

Class: 

Rule

Controls whether a pattern rule respects balanced bracket pairs, preventing matches from crossing structural boundaries like parentheses or braces.

Remarks

🛡️ Structural Integrity: The BracketSensitive Property

The BracketSensitive property controls whether a pattern is aware of nested, balanced bracket pairs. When enabled (the default), it prevents a variable capture from starting inside a bracketed block and ending outside of it, ensuring that structural units like function calls or code blocks are treated atomically.

This is a fundamental feature for safely parsing structured text and a key advantage over traditional regular expressions, which are not context-aware.

⚙️ How It Works

This property acts as a switch for a rule's parsing logic. The behavior can be set per-rule or globally via the Transformer.DefaultRuleSet.

SettingBehavior
true (Default)Structurally Aware. The parser tracks the nesting depth of brackets. A pattern like A {body} C will not match A (B C) because the closing parenthesis is missing. It correctly matches A (B) C.
falseStructurally Unaware. Brackets ((), [], {}) are treated like any other generic token. The parser will match across boundaries, which can be useful for certain kinds of text analysis but is generally less safe for structured data.

By default, uCalc recognizes (), [], and {} as bracket pairs. You can define your own custom pairs (e.g., begin/end or </>) using [uCalc.Tokens.Add](/Reference/uCalcBase/Tokens/Add/Add(string, TokenType, string, int, RegExGrammar, int)).

💡 Why uCalc? (Comparative Analysis)

Regular expressions are notoriously poor at handling nested or recursive structures. A simple regex like \((.*)\) is greedy and will fail to correctly parse nested calls like func(a, sub(b)). While modern regex engines have features like recursive patterns ((?R)), they are complex, difficult to maintain, and can lead to "catastrophic backtracking" performance issues.

uCalc's BracketSensitive property solves this elegantly by leveraging its token-based architecture:

  1. Tokenizer Awareness: The tokenizer identifies opening and closing brackets first, understanding their relationship.
  2. Parser State: When BracketSensitive is true, the parser uses this token information to maintain a nesting level counter.
  3. Safe Matching: A pattern variable's capture is only considered complete if the bracket nesting level is the same at the end as it was at the start.

This makes parsing structured, nested data in uCalc both safer and more performant than using regex alone.

Examples

BracketSensitive
				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
var Pattern = t.Pattern("< {etc} >");
t.Str("< a b c > d < (e f g) > h < (i) (j k) > l < m n o ( > p) q >");

// Note the difference in the final match

Pattern.BracketSensitive = true; // true is the default
Console.WriteLine($"BracketSensitive: {Pattern.BracketSensitive}");
Console.WriteLine("----------------------");
t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

Pattern.BracketSensitive = false;
Console.WriteLine($"BracketSensitive: {Pattern.BracketSensitive}");
Console.WriteLine("-----------------------");

t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

t.Str("( a b ( c ) d e )");
// Here parentheses are captured as regular tokens, not bracket pairs
var Pattern2a = t.Pattern("( {etc} (");
var Pattern2b = t.Pattern(") {etc} )");

Console.WriteLine("Brackets used as part of pattern");
Console.WriteLine("--------------------------------");
Pattern2a.BracketSensitive = true;
Pattern2b.BracketSensitive = true;
t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");
Pattern2a.BracketSensitive = false;
Pattern2b.BracketSensitive = false;
t.Find();
Console.WriteLine(t.Matches.Text);


				
			
BracketSensitive: True
----------------------
< a b c >
< (e f g) >
< (i) (j k) >
< m n o ( > p) q >

BracketSensitive: False
-----------------------
< a b c >
< (e f g) >
< (i) (j k) >
< m n o ( >

Brackets used as part of pattern
--------------------------------
( a b (
) d e )

( a b (
) d e )
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

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

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   auto Pattern = t.Pattern("< {etc} >");
   t.Str("< a b c > d < (e f g) > h < (i) (j k) > l < m n o ( > p) q >");

   // Note the difference in the final match

   Pattern.BracketSensitive(true); // true is the default
   cout << "BracketSensitive: " << tf(Pattern.BracketSensitive()) << endl;
   cout << "----------------------" << endl;
   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

   Pattern.BracketSensitive(false);
   cout << "BracketSensitive: " << tf(Pattern.BracketSensitive()) << endl;
   cout << "-----------------------" << endl;

   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

   t.Str("( a b ( c ) d e )");
   // Here parentheses are captured as regular tokens, not bracket pairs
   auto Pattern2a = t.Pattern("( {etc} (");
   auto Pattern2b = t.Pattern(") {etc} )");

   cout << "Brackets used as part of pattern" << endl;
   cout << "--------------------------------" << endl;
   Pattern2a.BracketSensitive(true);
   Pattern2b.BracketSensitive(true);
   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;
   Pattern2a.BracketSensitive(false);
   Pattern2b.BracketSensitive(false);
   t.Find();
   cout << t.Matches().Text() << endl;


}
				
			
BracketSensitive: True
----------------------
< a b c >
< (e f g) >
< (i) (j k) >
< m n o ( > p) q >

BracketSensitive: False
-----------------------
< a b c >
< (e f g) >
< (i) (j k) >
< m n o ( >

Brackets used as part of pattern
--------------------------------
( a b (
) d e )

( a b (
) d e )
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      Dim Pattern = t.Pattern("< {etc} >")
      t.Str("< a b c > d < (e f g) > h < (i) (j k) > l < m n o ( > p) q >")
      
      '// Note the difference in the final match
      
      Pattern.BracketSensitive = true '// true is the default
      Console.WriteLine($"BracketSensitive: {Pattern.BracketSensitive}")
      Console.WriteLine("----------------------")
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
      Pattern.BracketSensitive = false
      Console.WriteLine($"BracketSensitive: {Pattern.BracketSensitive}")
      Console.WriteLine("-----------------------")
      
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
      t.Str("( a b ( c ) d e )")
      '// Here parentheses are captured as regular tokens, not bracket pairs
      Dim Pattern2a = t.Pattern("( {etc} (")
      Dim Pattern2b = t.Pattern(") {etc} )")
      
      Console.WriteLine("Brackets used as part of pattern")
      Console.WriteLine("--------------------------------")
      Pattern2a.BracketSensitive = true
      Pattern2b.BracketSensitive = true
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      Pattern2a.BracketSensitive = false
      Pattern2b.BracketSensitive = false
      t.Find()
      Console.WriteLine(t.Matches.Text)
      
      
   End Sub
End Module
				
			
BracketSensitive: True
----------------------
< a b c >
< (e f g) >
< (i) (j k) >
< m n o ( > p) q >

BracketSensitive: False
-----------------------
< a b c >
< (e f g) >
< (i) (j k) >
< m n o ( >

Brackets used as part of pattern
--------------------------------
( a b (
) d e )

( a b (
) d e )