mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 05:42:56 +08:00
Replace regex with a custom algorithm and update test scene.
This commit is contained in:
parent
23c20ca5f4
commit
c927f90a48
@ -19,7 +19,7 @@ namespace osu.Game.Tests.SongSelect
|
||||
("Title1", "Diff2"),
|
||||
("My[Favourite]Song", "Expert"),
|
||||
("Title", "My Favourite Diff"),
|
||||
("Another One", "diff ]with [[] brackets]]]"),
|
||||
("Another One", "diff ]with [[ brackets]]]"),
|
||||
};
|
||||
|
||||
[TestCase("[1]", new[] { 0 })]
|
||||
@ -34,7 +34,8 @@ namespace osu.Game.Tests.SongSelect
|
||||
[TestCase("Title1 [Diff]", new[] { 0, 1 })]
|
||||
[TestCase("Title1[Diff]", new int[] { })]
|
||||
[TestCase("[diff ]with]", new[] { 4 })]
|
||||
[TestCase("[diff ]with [[] brackets]]]]", new[] { 4 })]
|
||||
[TestCase("[diff ]with [[ brackets]]]]", new[] { 4 })]
|
||||
[TestCase("[diff] another [brackets]", new[] { 4 })]
|
||||
public void TestDifficultySearch(string query, int[] expectedBeatmapIndexes)
|
||||
{
|
||||
var carouselBeatmaps = createCarouselBeatmaps().ToList();
|
||||
|
@ -19,30 +19,9 @@ namespace osu.Game.Screens.Select
|
||||
@"\b(?<key>\w+)(?<op>(:|=|(>|<)(:|=)?))(?<value>("".*""[!]?)|(\S*))",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex difficulty_query_syntax_regex = new Regex(
|
||||
@"(\s|^)((\[(?>\[(?<level>)|[^[\]]+|\](?<-level>))*(?(level)(?!))\](\s|$))|(\[.*))",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
internal static void ApplyQueries(FilterCriteria criteria, string query)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var match = difficulty_query_syntax_regex.Matches(query).FirstOrDefault();
|
||||
|
||||
if (match is null) break;
|
||||
|
||||
// Trim the first character because it's always '[' (ignoring spaces)
|
||||
string cleanDifficultyQuery = match.Value.Trim(' ')[1..];
|
||||
|
||||
if (cleanDifficultyQuery.EndsWith(']'))
|
||||
cleanDifficultyQuery = cleanDifficultyQuery[..^1];
|
||||
|
||||
criteria.DifficultySearchText = cleanDifficultyQuery;
|
||||
|
||||
// Insert whitespace if necessary so that the words before and after the difficulty query aren't joined together.
|
||||
bool insertWhitespace = match.Value.StartsWith(' ') && match.Value.EndsWith(' ');
|
||||
query = query.Replace(match.Value, insertWhitespace ? " " : "");
|
||||
}
|
||||
criteria.DifficultySearchText = extractDifficultySearchText(ref query);
|
||||
|
||||
foreach (Match match in query_syntax_regex.Matches(query))
|
||||
{
|
||||
@ -57,6 +36,73 @@ namespace osu.Game.Screens.Select
|
||||
criteria.SearchText = query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts and returns the difficulty search text between square brackets.
|
||||
/// </summary>
|
||||
/// <param name="query">The search query. The difficulty search text will be removed from the query.</param>
|
||||
/// <returns>The difficulty search text (without the square brackets).</returns>
|
||||
private static string extractDifficultySearchText(ref string query)
|
||||
{
|
||||
var openingBracketIndexes = new List<int>();
|
||||
var closingBracketIndexes = new List<int>();
|
||||
|
||||
populateIndexLists(ref query);
|
||||
|
||||
return performExtraction(ref query);
|
||||
|
||||
void populateIndexLists(ref string query)
|
||||
{
|
||||
bool currentlyBetweenBrackets = false;
|
||||
|
||||
for (int i = 0; i < query.Length; i++)
|
||||
{
|
||||
switch (query[i])
|
||||
{
|
||||
case '[' when !currentlyBetweenBrackets && (i == 0 || query[i - 1] == ' '):
|
||||
currentlyBetweenBrackets = true;
|
||||
openingBracketIndexes.Add(i + 1);
|
||||
break;
|
||||
|
||||
case ']' when currentlyBetweenBrackets && (i == query.Length - 1 || query[i + 1] == ' '):
|
||||
currentlyBetweenBrackets = false;
|
||||
closingBracketIndexes.Add(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentlyBetweenBrackets)
|
||||
{
|
||||
// If there is no "]" closing the current difficulty search query, append it.
|
||||
query += ']';
|
||||
closingBracketIndexes.Add(query.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
string performExtraction(ref string query)
|
||||
{
|
||||
var searchTexts = new List<string>();
|
||||
string originalQuery = query;
|
||||
|
||||
for (int i = 0; i < openingBracketIndexes.Count; i++)
|
||||
{
|
||||
int startIndex = openingBracketIndexes[i];
|
||||
int endIndex = closingBracketIndexes[i];
|
||||
|
||||
string searchText = originalQuery[startIndex..endIndex];
|
||||
|
||||
searchTexts.Add(searchText);
|
||||
|
||||
query = query
|
||||
.Replace($" [{searchText}]", "")
|
||||
.Replace($"[{searchText}] ", "")
|
||||
.Replace($"[{searchText}]", "")
|
||||
.Replace($" [{searchText}] ", " ");
|
||||
}
|
||||
|
||||
return string.Join(' ', searchTexts);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool tryParseKeywordCriteria(FilterCriteria criteria, string key, string value, Operator op)
|
||||
{
|
||||
switch (key)
|
||||
|
Loading…
Reference in New Issue
Block a user