Class BalancedGroup
find(java.lang.CharSequence, java.lang.String, java.lang.String),
also exposed on CharSequence via
StringGroovyMethods.findBalancedGroups(CharSequence, String, String).
Java's Pattern has no .NET-style balancing groups
((?<name1-name2>…)). This type is both the structured result and the
entry point for Groovy's stack-based equivalent: each node is one successfully
closed span, with immediately nested spans as children (richer than .NET's flat
CaptureCollection on a single group).
Offsets mirror .NET Capture.Index / Length: getStart()
and getEnd() describe the range of getMatchedString() in the
original input (half-open [start, end)). getFullStart() /
getFullEnd() always cover the complete pair including delimiters,
even when BalancedGroup.MatchOptions.includeEdges() is false (comparable to
knowing both the balancing capture and the open/close match positions).
Parent links and nesting depth are wired when a node is attached as a child
of another node during construction; root nodes have a null parent
and depth 0. Prefer find(java.lang.CharSequence, java.lang.String, java.lang.String) (or the GDK methods on
CharSequence) as the public entry point — constructors are
package-private because they perform one-shot parent wiring.
- Since:
- 6.0.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordOptions controlling balanced-group matching. -
Method Summary
Modifier and TypeMethodDescriptionstatic List<BalancedGroup>find(CharSequence text, String openRegex, String closeRegex) Finds balanced groups usingBalancedGroup.MatchOptions.defaults().static List<BalancedGroup>find(CharSequence text, String openRegex, String closeRegex, BalancedGroup.MatchOptions options) Finds balanced (nested) groups intextand returns them as a forest ofBalancedGroupnodes.Returns the immediately nested balanced groups.intgetDepth()Nesting depth of this node (0 for a root).intgetEnd()End index ofgetMatchedString()in the original input (exclusive).intEnd index of the full balanced pair, always including the closing delimiter (exclusive).intStart index of the full balanced pair, always including the opening delimiter.intLength ofgetMatchedString()(end - start).Returns the text captured for this group.Returns the enclosing group, if any.intgetStart()Start index ofgetMatchedString()in the original input (inclusive).toString()Returns the matched text of this group.
-
Method Details
-
find
Finds balanced groups usingBalancedGroup.MatchOptions.defaults().- Parameters:
text- text to scanopenRegex- regex for an opening delimiter (must not be empty)closeRegex- regex for a closing delimiter (must not be empty)- Returns:
- unmodifiable list of outermost groups (empty if none)
- Since:
- 6.0.0
- See Also:
-
find
public static List<BalancedGroup> find(CharSequence text, String openRegex, String closeRegex, BalancedGroup.MatchOptions options) Finds balanced (nested) groups intextand returns them as a forest ofBalancedGroupnodes.Relation to .NET balancing groups: .NET keeps a capture stack per named group, pushes with
(?<Open>…), pops with(?<-Open>…)or(?<Between-Open>…), and can require a fully empty stack via(?(Open)(?!)). This method uses the same push/pop idea on an explicit stack, but returns a hierarchical tree (children + parent) rather than a flatCaptureCollection, and always extracts every completed span in one left-to-right scan.Algorithm: matches of a combined tokenizer (
IGNORE? /OPEN/CLOSE) are consumed in order. Nesting is resolved by the stack, not by recursive regex, so balancing itself does not introduce ReDoS; cost is proportional to the number of tokenizer hits times the cost of the user-supplied patterns. Compiled tokenizers are cached (bounded LRU).Fault tolerance (differs from a strict .NET
(?(Open)(?!))pattern): unmatched closers are ignored; unclosed openers are dropped at end-of-input, but groups already completed inside them are promoted outward ("orphan rescue").Named capturing groups
OPEN,CLOSE, andIGNOREare reserved for the tokenizer; do not use those names insideopenRegex,closeRegex, orBalancedGroup.MatchOptions.ignoreRegex().- Parameters:
text- text to scanopenRegex- regex for an opening delimiter (must not be empty)closeRegex- regex for a closing delimiter (must not be empty)options- match options;nullmeansBalancedGroup.MatchOptions.defaults()- Returns:
- unmodifiable list of outermost groups (empty if none)
- Throws:
NullPointerException- iftext,openRegex, orcloseRegexisnullIllegalArgumentException- ifopenRegexorcloseRegexis emptyPatternSyntaxException- if a supplied pattern is not a valid Java regex- Since:
- 6.0.0
-
getMatchedString
Returns the text captured for this group.- Returns:
- the matched text (never
null); may include or exclude boundary delimiters depending onBalancedGroup.MatchOptions.includeEdges()
-
getStart
public int getStart()Start index ofgetMatchedString()in the original input (inclusive). Comparable to .NETCapture.Index.- Returns:
- the start offset
-
getEnd
public int getEnd()End index ofgetMatchedString()in the original input (exclusive). Length isgetEnd() - getStart(), like .NETCapture.Length.- Returns:
- the end offset
-
getLength
public int getLength()Length ofgetMatchedString()(end - start).- Returns:
- the length
-
getFullStart
public int getFullStart()Start index of the full balanced pair, always including the opening delimiter.- Returns:
- the full-span start offset
-
getFullEnd
public int getFullEnd()End index of the full balanced pair, always including the closing delimiter (exclusive).- Returns:
- the full-span end offset
-
getChildren
Returns the immediately nested balanced groups.- Returns:
- an unmodifiable list of children; empty (never
null) for a leaf
-
getParent
Returns the enclosing group, if any.- Returns:
- the parent node, or
nullif this is a root
-
getDepth
public int getDepth()Nesting depth of this node (0 for a root). Computed once when the parent link is wired; O(1).- Returns:
- the number of ancestors
-
toString
Returns the matched text of this group.- Overrides:
toStringin classObject- Returns:
- the same value as
getMatchedString()
-