/// <summary> /// Search for e.g. -Tags:"test" /// </summary> /// <param name="model">Model</param> /// <param name="itemName">e.g. Tags or Description</param> private void SearchItemName(SearchViewModel model, string itemName) { // ignore double quotes model.SearchQuery = model.SearchQuery.Replace("\"\"", "\""); // Escape special quotes model.SearchQuery = Regex.Replace(model.SearchQuery, "[“”‘’]", "\""); // Without double escapes: // (:|=|;|>|<)(([\w\!\~\-_\.\/:]+)|(\"|').+(\"|')) // new: unescaped // (:|=|;|>|<|-)((["'])(\\?.)*?\3|[\w\!\~\-_\.\/:]+)( \|\|| \&\&)? Regex inurlRegex = new Regex( "-" + itemName + "(:|=|;|>|<|-)(([\"\'])(\\\\?.)*?\\3|[\\w\\!\\~\\-_\\.\\/:]+)( \\|\\|| \\&\\&)?", RegexOptions.IgnoreCase); _defaultQuery = inurlRegex.Replace(_defaultQuery, ""); // the current query is removed from the list, so the next item will not search on it var regexInUrlMatches = inurlRegex.Matches(model.SearchQuery); if (regexInUrlMatches.Count == 0) { return; } foreach (Match regexInUrl in regexInUrlMatches) { var itemQuery = regexInUrl.Value; // ignore fake results if (string.IsNullOrEmpty(itemQuery)) { continue; } // put ||&& in operator field => next regex > removed model.SetAndOrOperator(model.AndOrRegex(itemQuery)); Regex rgx = new Regex("-" + itemName + "(:|=|;|>|<|-)", RegexOptions.IgnoreCase); // To Search Type var itemNameSearch = rgx.Match(itemQuery).Value; if (!itemNameSearch.Any()) { continue; } // replace itemQuery = rgx.Replace(itemQuery, string.Empty); // Option last of itemNameSearch var searchForOption = itemNameSearch[itemNameSearch.Length - 1].ToString(); model.SetAddSearchForOptions(searchForOption); // Remove parenthesis itemQuery = itemQuery.Replace("\"", string.Empty); itemQuery = itemQuery.Replace("'", string.Empty); // Remove || / && at the end of the string // (\|\||\&\&)$ string pattern = "(\\|\\||\\&\\&)$"; itemQuery = Regex.Replace(itemQuery, pattern, string.Empty); model.SetAddSearchFor(itemQuery.Trim()); model.SetAddSearchInStringType(itemName); } }