private MatchScore FindEndOfMatch(string targetString, string chars, int score, int firstIndex, ImmutableHashSet <int> matchSet) { var lastIndex = firstIndex; var lastMatch = MatchType.Undefined; if (firstIndex == 0 || !char.IsLetterOrDigit(targetString[firstIndex - 1])) { lastMatch = MatchType.Boundary; } foreach (var c in chars) { var index = targetString.IndexOf(c, lastIndex + 1); if (index == -1) { return(null); } if (index == lastIndex + 1) { if (lastMatch != MatchType.Sequential) { score += 1; lastMatch = MatchType.Sequential; } } else if (!char.IsLetterOrDigit(targetString[index - 1])) { if (lastMatch != MatchType.Boundary) { score += 1; lastMatch = MatchType.Boundary; } } else { score += index - lastIndex; lastMatch = MatchType.Normal; } lastIndex = index; matchSet = matchSet.Add(index); } return(MatchScore.Create(score, new Range(firstIndex, lastIndex), matchSet)); }
private static MatchScore GetBestMatch(string searchString, string targetString, int?lastIndex, int score, ImmutableHashSet <int> matchedIndexes, MatchType lastMatch) { if (searchString.Length == 0) { return(MatchScore.Create(score, new Range(0, 0), matchedIndexes)); } var searchChar = char.ToLowerInvariant(searchString.First()); var bestMatch = NoMatch; for (var i = lastIndex + 1 ?? 0; i < targetString.Length; i++) { if (char.ToLowerInvariant(targetString[i]) == searchChar) { MatchType matchType; var nextScore = score; if (i == lastIndex + 1) { matchType = MatchType.Sequential; } else if (i == 0 || !char.IsLetterOrDigit(targetString[i - 1]) || !char.IsLetterOrDigit(targetString[i])) { matchType = MatchType.Boundary; } else if (char.IsLower(targetString[i - 1]) && char.IsUpper(targetString[i])) { matchType = MatchType.Boundary; } else { matchType = MatchType.Normal; } if (lastMatch == MatchType.Normal) { if (lastIndex.HasValue) { nextScore += i - lastIndex.Value; } } else if (lastMatch == MatchType.Boundary || lastMatch == MatchType.Sequential) { if (matchType == MatchType.Normal) { if (lastIndex.HasValue) { nextScore += i - lastIndex.Value; } } } if (Mode == SelectaMode.Strict && matchType == MatchType.Normal) { continue; } var match = GetBestMatch(searchString.Substring(1), targetString, i, nextScore, matchedIndexes.Add(i), matchType); if (match.Score < bestMatch.Score) { bestMatch = match; } } } return(bestMatch); }