match method
Should return the matches for the password
.
A synchronous matcher should return a list (usually of length 1) of lists of matches. An asynchronous matcher can return a list of futures that completes with a list of matches.
Implementation
@override
List<List<SeparatorMatch>> match(String password) {
final List<SeparatorMatch> result = <SeparatorMatch>[];
final List<MapEntry<String, int>> mostUsedSeparators = password
.split('')
.where(separators.contains)
.fold(<String, int>{}, (Map<String, int> counts, String separator) {
counts[separator] = (counts[separator] ?? 0) + 1;
return counts;
})
.entries
.toList()
..sort(
(MapEntry<String, int> a, MapEntry<String, int> b) =>
b.value.compareTo(a.value),
);
// If the special character is only used once, don't treat it like
// a separator.
if (mostUsedSeparators.isEmpty || mostUsedSeparators[0].value < 2) {
return <List<SeparatorMatch>>[result];
}
final String separator = mostUsedSeparators[0].key;
final RegExp separatorRegExp =
RegExp('([^$separator\n])($separator)(?!$separator)');
for (final RegExpMatch match in separatorRegExp.allMatches(password)) {
// Add one to the index because we changed the regex from negative
// lookbehind to something simple. This simple approach uses the first
// character before the separator too but we only need the index of the
// separator.
final int start = match.start + 1;
result.add(
SeparatorMatch(
password: password,
start: start,
end: start + 1,
),
);
}
return <List<SeparatorMatch>>[result];
}