keyMatch4 function
KeyMatch4 determines whether key1
matches the pattern of key2
(similar to RESTful path),
key2
can contain a *.
Besides what KeyMatch3 does, KeyMatch4 can also match repeated patterns:
"/parent/123/child/123" matches "/parent/{id}/child/{id}" "/parent/123/child/456" does not match "/parent/{id}/child/{id}" But KeyMatch3 will match both.
Attention: key1
cannot contain English commas.
Implementation
bool keyMatch4(String key1, String key2) {
var regEx = RegExp('\\{[^/]+}');
var m = regEx.allMatches(key2).toList();
var t = key2.split(regEx);
var tokens = <String>[];
if (t.isNotEmpty) {
var cnt = 0;
while (cnt < t.length) {
tokens.add(t[cnt]);
if (cnt < m.length) {
tokens.add(m[cnt].group(0)!);
}
cnt++;
}
}
var off = 0;
for (var token in tokens) {
if (!regEx.hasMatch(token) && token.isNotEmpty) {
while (off < key1.length && key1[off] != token[0]) {
off++;
}
if (key1.length - (off + 1) < token.length) {
return false;
}
if (key1.substring(off, off + token.length) != token) {
return false;
}
key1 = key1.replaceFirst(token, ',');
}
}
var values = key1.split(',');
var i = 0;
var params = <String, String>{};
for (var token in tokens) {
if (regEx.hasMatch(token)) {
while (i < values.length && values[i] == '') {
i++;
}
if (i == values.length) {
return false;
}
if (params.containsKey(token)) {
if (values[i] != params[token]) {
return false;
}
} else {
params[token] = values[i];
}
i++;
}
}
return true;
}