/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.
/**
* @file The file declares the MatchData class.
*/
package std.regex
const UNCAPTURED_GROUP_INDEX: Int64 = -1
public struct Position {
static let empty = Position(0, 0)
Position(public let start: Int64, public let end: Int64) {}
@OverflowWrapping
init(start: UIntNative, end: UIntNative) {
this.start = Int64(start)
this.end = Int64(end)
}
}
public struct MatchData {
MatchData(
let input: String,
let positions: Array<Position>,
let rc: Int64,
let nameToIndex!: (String) -> Int64 = {
_ => throw IllegalArgumentException("Capture group not enabled.")
}
) {}
/**
* Retrive the whole matched string.
*/
public func matchString(): String {
let position = positions[0]
return input[position.start..position.end]
}
/**
* Retrive the subsequence of capture group by index.
*
* @throws IndexOutOfBoundsException if capture group not enabled, or group is less than zero or larger than groupCount()
*/
public func matchString(group: Int64): String {
if (positions.size == 1 && rc > 1 && group > 0) {
throw IllegalArgumentException("Capture group not enabled.")
}
if (group < 0 || group >= rc) {
throw IllegalArgumentException("Invalid group index.")
}
let position = positions[group]
if (position.start == UNCAPTURED_GROUP_INDEX || position.end == UNCAPTURED_GROUP_INDEX) {
return String.empty
}
return input[position.start..position.end]
}
/**
* Retrive the subsequence of capture group by name.
*
* @throws IllegalArgumentException if capture group not enabled or group name not found
*/
public func matchString(group: String): String {
if (positions.size == 1 && rc > 1) {
throw IllegalArgumentException("Capture group not enabled.")
}
let index = nameToIndex(group)
let position = positions[index]
if (position.start == UNCAPTURED_GROUP_INDEX || position.end == UNCAPTURED_GROUP_INDEX) {
return String.empty
}
return input[position.start..position.end]
}
/**
* Retrive the position of whole matched string.
*
* @throws IndexOutOfBoundsException if the length of `position` is less than 1
*/
public func matchPosition(): Position {
return positions[0]
}
/**
* Retrive the position of the capture group subsequence by index.
*
* @throws IllegalArgumentException if capture group not enabled, or group is less than zero or larger than groupCount
*/
public func matchPosition(group: Int64): Position {
if (positions.size == 1 && rc > 1 && group > 0) {
throw IllegalArgumentException("Capture group not enabled.")
}
if (group < 0 || group >= rc) {
throw IllegalArgumentException("Invalid group index.")
}
return positions[group]
}
/**
* Retrive the position of the capture group subsequence by index.
*
* @throws IllegalArgumentException if capture group not enabled or group name not found
*/
public func matchPosition(group: String): Position {
if (positions.size == 1 && rc > 1) {
throw IllegalArgumentException("Capture group not enabled.")
}
let index = nameToIndex(group)
return positions[index]
}
@Deprecated[message: "Use member function `public func groupCount(): Int64` instead."]
public func groupNumber(): Int64 {
return groupCount()
}
/**
* Get the count of capture groups.
*/
public func groupCount(): Int64 {
return rc - 1
}
}