Skip to content

Commit 8f8a294

Browse files
Improve the group impl
1 parent 453fa81 commit 8f8a294

File tree

2 files changed

+57
-76
lines changed

2 files changed

+57
-76
lines changed

ballerina/natives.bal

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,16 @@ public isolated function split(string receiver, string delimiter) returns string
146146
public isolated function search(string str, string regex, int startIndex = 0) returns Match? {
147147
string extractedString = getSubstring(str, startIndex);
148148
handle matcher = getMatcher(extractedString, regex);
149+
int groupCount = getGroupCount(matcher);
149150
if isMatched(matcher) {
150-
handle group = getGroup(matcher, 0);
151-
string? value = java:toString(group);
152-
if value is string {
153-
Match matched = {
154-
matched: value,
155-
startIndex: getStartIndex(matcher) + startIndex,
156-
endIndex: getEndIndex(matcher) + startIndex,
157-
groups: new MatchGroups(matcher, startIndex)
158-
};
159-
return matched;
160-
}
151+
PartMatch[] partMatch = getPartMatch(matcher, groupCount, startIndex);
152+
Match matched = {
153+
matched: partMatch[0].matched,
154+
startIndex: partMatch[0].startIndex,
155+
endIndex: partMatch[0].endIndex,
156+
groups: new MatchGroups(partMatch, groupCount)
157+
};
158+
return matched;
161159
}
162160
return ();
163161
}
@@ -174,23 +172,38 @@ public isolated function search(string str, string regex, int startIndex = 0) re
174172
public isolated function searchAll(string str, string regex) returns Match[] {
175173
handle matcher = getMatcher(str, regex);
176174
Match[] matched = [];
175+
int groupCount = getGroupCount(matcher);
177176
while isMatched(matcher) {
178-
handle group = getGroup(matcher, 0);
177+
PartMatch[] partMatch = getPartMatch(matcher, groupCount);
178+
matched.push(
179+
{
180+
matched: partMatch[0].matched,
181+
startIndex: partMatch[0].startIndex,
182+
endIndex: partMatch[0].endIndex,
183+
groups: new MatchGroups(partMatch, groupCount)
184+
});
185+
}
186+
return matched;
187+
}
188+
189+
isolated function getPartMatch(handle matcher, int groupCount, int startIndex = 0) returns PartMatch[] {
190+
int i = 0;
191+
PartMatch[] partMatch = [];
192+
while i <= groupCount {
193+
handle group = getGroup(matcher, i);
179194
string? valueInString = java:toString(group);
180195
if valueInString is string {
181-
int startIndex = getStartIndex(matcher);
182-
matched.push(
196+
partMatch.push(
183197
{
184198
matched: valueInString,
185-
startIndex: startIndex,
186-
endIndex: getEndIndex(matcher),
187-
groups: new MatchGroups(matcher, startIndex, regex, valueInString)
199+
startIndex: getGroupStartIndex(matcher, i) + startIndex,
200+
endIndex: getGroupEndIndex(matcher, i) + startIndex
188201
});
189202
}
203+
i += 1;
190204
}
191-
return matched;
205+
return partMatch;
192206
}
193-
194207
// Interoperable external functions.
195208
isolated function matchesExternal(handle stringToMatch, handle regex) returns boolean = @java:Method {
196209
name: "matches",
@@ -242,8 +255,24 @@ isolated function getEndIndex(handle matcherObj) returns int = @java:Method {
242255
'class: "java.util.regex.Matcher"
243256
} external;
244257

245-
// handle exceptions
246258
isolated function regexCompile(handle regex) returns handle = @java:Method {
247259
name: "compile",
248260
'class: "java.util.regex.Pattern"
249261
} external;
262+
263+
isolated function getGroupStartIndex(handle matcherObj, int index) returns int = @java:Method {
264+
name: "start",
265+
'class: "java.util.regex.Matcher",
266+
paramTypes: ["int"]
267+
} external;
268+
269+
isolated function getGroupEndIndex(handle matcherObj, int index) returns int = @java:Method {
270+
name: "end",
271+
'class: "java.util.regex.Matcher",
272+
paramTypes: ["int"]
273+
} external;
274+
275+
isolated function getGroupCount(handle matcherObj) returns int = @java:Method {
276+
name: "groupCount",
277+
'class: "java.util.regex.Matcher"
278+
} external;

ballerina/utils.bal

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -40,68 +40,20 @@ isolated function getMatcher(string str, string regex) returns handle {
4040
readonly class MatchGroups {
4141

4242
*Groups;
43-
private handle matcher;
44-
private int startIndex;
45-
private string? value;
46-
private string regex;
43+
private PartMatch[] partMatch;
4744

48-
isolated function init(handle matcher, int startIndex, string regex = "", string? value = ()) {
49-
self.matcher = matcher;
50-
self.startIndex = startIndex;
51-
self.value = value;
52-
self.regex = regex;
53-
self.count = getGroupCount(matcher);
45+
isolated function init(PartMatch[] partMatch, int groupCount) {
46+
self.partMatch = partMatch.cloneReadOnly();
47+
self.count = groupCount;
5448
}
5549

5650
isolated function get(int index) returns PartMatch? {
57-
if (index < 0 || index > self.count) {
51+
if index < 0 || index > self.count {
5852
panic error("There is no capturing group in the pattern with the given index " + index.toString() + ".");
5953
}
60-
if self.value is string { // Getting the group data for the`searchAll` group(i)
61-
Match? matched = search(self.value.toString(), self.regex.toString());
62-
if matched is Match {
63-
PartMatch? partMatched = matched.groups.get(index);
64-
if partMatched is PartMatch {
65-
partMatched = {
66-
matched: partMatched.matched,
67-
startIndex: partMatched.startIndex + self.startIndex,
68-
endIndex: partMatched.endIndex + self.startIndex
69-
};
70-
}
71-
return partMatched;
72-
}
73-
} else {
74-
handle|error group = trap getGroup(self.matcher, index);
75-
if group is error {
76-
return null; // IllegalStateException(No match found)
77-
}
78-
string? valueInString = java:toString(group);
79-
if valueInString is string {
80-
PartMatch partMatch = {
81-
matched: valueInString,
82-
startIndex: getGroupStartIndex(self.matcher, index) + self.startIndex,
83-
endIndex: getGroupEndIndex(self.matcher, index) + self.startIndex
84-
};
85-
return partMatch;
86-
}
54+
if self.partMatch.length() == 0 {
55+
return ();
8756
}
88-
return null;
57+
return self.partMatch[index];
8958
}
9059
}
91-
92-
isolated function getGroupStartIndex(handle matcherObj, int index) returns int = @java:Method {
93-
name: "start",
94-
'class: "java.util.regex.Matcher",
95-
paramTypes: ["int"]
96-
} external;
97-
98-
isolated function getGroupEndIndex(handle matcherObj, int index) returns int = @java:Method {
99-
name: "end",
100-
'class: "java.util.regex.Matcher",
101-
paramTypes: ["int"]
102-
} external;
103-
104-
isolated function getGroupCount(handle matcherObj) returns int = @java:Method {
105-
name: "groupCount",
106-
'class: "java.util.regex.Matcher"
107-
} external;

0 commit comments

Comments
 (0)