Ключевое слово поиска в ASP.Net - PullRequest
7 голосов
/ 27 октября 2009

Я выводлю список результатов поиска для заданной строки ключевых слов и хочу, чтобы любые соответствующие ключевые слова в моих результатах поиска были выделены. Каждое слово должно быть заключено в интервал или аналогичный. Я ищу эффективную функцию для этого.

* 1003 Е.Г. *

Ключевые слова: "lorem ipsum"

Результат: "Некоторый текст, содержащий лорем и ипсум"

Требуемый вывод HTML: "Some text containing <span class="hit">lorem</span> and <span class="hit">ipsum</span>"

Мои результаты не чувствительны к регистру.

Ответы [ 5 ]

13 голосов
/ 27 октября 2009

Вот что я решил. Функция расширения, которую я могу вызвать в соответствующих строках на моей странице / разделе моей страницы:

public static string HighlightKeywords(this string input, string keywords)
{
    if (input == string.Empty || keywords == string.Empty)
    {
        return input;
    }

    string[] sKeywords = keywords.Split(' ');
    foreach (string sKeyword in sKeywords)
    {
        try
        {
            input = Regex.Replace(input, sKeyword, string.Format("<span class=\"hit\">{0}</span>", "$0"), RegexOptions.IgnoreCase);
        }
        catch
        {
            //
        }
    }
    return input;
}

Есть еще предложения или комментарии?

1 голос
/ 27 октября 2009

Используйте плагин подсветки jquery.

Для выделения на стороне сервера

protected override void Render( HtmlTextWriter writer )
{
    StringBuilder html = new StringBuilder();
    HtmlTextWriter w = new HtmlTextWriter( new StringWriter( html ) );

    base.Render( w );

    html.Replace( "lorem", "<span class=\"hit\">lorem</span>" );

    writer.Write( html.ToString() );
}

Вы можете использовать регулярные выражения для расширенной замены текста.

Вы также можете написать приведенный выше код в HttpModule, чтобы его можно было использовать в других приложениях.

1 голос
/ 27 октября 2009

попробуйте подсветку от Lucene.net

http://incubator.apache.org/lucene.net/docs/2.0/Highlighter.Net/Lucene.Net.Highlight.html

Как использовать:

http://davidpodhola.blogspot.com/2008/02/how-to-highlight-phrase-on-results-from.html

EDIT: Пока маркер Lucene.net не подходит здесь новая ссылка:

http://mhinze.com/archive/search-term-highlighter-httpmodule/

0 голосов
/ 13 декабря 2013

Расширение до ответа выше. (не хватает репутации, чтобы комментировать)

Чтобы избежать замены span, когда критерии поиска были [span pan a a], найденное слово было заменено чем-то другим, кроме замены back ... хотя и не очень эффективным ...

public string Highlight(string input)
{
    if (input == string.Empty || searchQuery == string.Empty)
    {
        return input;
    }

    string[] sKeywords = searchQuery.Replace("~",String.Empty).Replace("  "," ").Trim().Split(' ');
    int totalCount = sKeywords.Length + 1;
    string[] sHighlights = new string[totalCount];
    int count = 0;

    input = Regex.Replace(input, Regex.Escape(searchQuery.Trim()), string.Format("~{0}~", count), RegexOptions.IgnoreCase);
    sHighlights[count] = string.Format("<span class=\"highlight\">{0}</span>", searchQuery);
    foreach (string sKeyword in sKeywords.OrderByDescending(s => s.Length))
    {
        count++;
        input = Regex.Replace(input, Regex.Escape(sKeyword), string.Format("~{0}~", count), RegexOptions.IgnoreCase);
        sHighlights[count] = string.Format("<span class=\"highlight\">{0}</span>", sKeyword);
    }

    for (int i = totalCount - 1; i >= 0; i--)
    {
        input = Regex.Replace(input, "\\~" + i + "\\~", sHighlights[i], RegexOptions.IgnoreCase);
    }

    return input;
}
0 голосов
/ 30 марта 2012

Я получил аналогичное требование в ASP.NET. Вот мое решение, написанное на C # для ключевого слова highlight.

Используется также алгоритм наивного поиска.

  • Поддерживать хеш-таблицу для хранения матчей.
  • Применить теги к строке, где есть совпадение ключевых слов.

    Подсветка региона

        /// <summary>
        /// Higlight the search term.
        /// </summary>
        /// <param name="currentString"></param>
        /// <returns></returns>
        private string Highlight(string currentString)
        {
            try
            {
                var termValue = _helperRequest.SearchText;
                if (!string.IsNullOrEmpty(currentString) && !string.IsNullOrEmpty(termValue))
                {
                    currentString = termValue.Trim().Split(Constants.Separator)
                                                    .ToList().Where(x => x.Length >1)
                                                    .Distinct()
                                                    .OrderByDescending(x => x.Length)
                                                    .Aggregate(currentString, (current, keyWord) =>
                                                     TagIndexers(new SearchHelperRequest() { SearchString = current, SearchTerm = keyWord, HightlightCss = _helperRequest.HightlightCss, Comparison = StringComparison.InvariantCultureIgnoreCase, TagIdentifier = GetRandomKey() }));
                }
            }
            catch (Exception ex)
            {
                Logger.WriteError(string.Format("Highlight Error : {0}", ex.Message));
            }
            finally
            {
                //Replace tags with highlight terms.
                if (_helperRequest != null)
                {
                    if (_helperRequest.TagKeyLookup.Keys.Count > 0)
                    {
                        foreach (string tagKey in _helperRequest.TagKeyLookup.Keys)
                        {
                            if (!string.IsNullOrEmpty(currentString))
                                currentString = currentString.Replace(tagKey, _helperRequest.TagKeyLookup[tagKey]);
                        }
    
                        //clear the key list.
                        _helperRequest.TagKeyLookup.Clear();
                    }
                }
            }
            return HttpUtility.JavaScriptStringEncode(currentString);
        }
        /// <summary>
        /// Generate a randome key from lookup table. Recurrsive in  nature.
        /// </summary>
        /// <returns></returns>
        private string GetRandomKey()
        {
            //config your key length
            var charBuffer = new char[4];
            lock (charBuffer)
            {
                for (var iCounter = 0; iCounter < charBuffer.Length; iCounter++)
                {
                    charBuffer[iCounter] = CharacterLookup
                        [new Random().Next(CharacterLookup.Length)];
                }
            }
            //Recurssion to generate random.
            return _helperRequest.TagKeyLookup.
                ContainsKey(new String(charBuffer))
                ? GetRandomKey() : new String(charBuffer);
        }
        /// <summary>
        /// Replace the term with identifiers
        /// </summary>
        /// <param name="searchRequest"></param>
        /// <returns></returns>
        private string TagIndexers(SearchHelperRequest searchRequest)
        {
            try
            {
                var highlightBulder = new StringBuilder();
                string spanValue = string.Empty;
                if (!string.IsNullOrEmpty(searchRequest.SearchString) && !string.IsNullOrEmpty(searchRequest.SearchTerm))
                {
                    int previousIndex = 0;
                    int currentIndex = searchRequest.SearchString.IndexOf(searchRequest.SearchTerm, searchRequest.Comparison);
                    while (currentIndex != -1)
                    {
                        highlightBulder.Append(searchRequest.SearchString.Substring(previousIndex, currentIndex - previousIndex));
                        spanValue = string.Format(searchRequest.HightlightCss, searchRequest.SearchString.Substring(currentIndex, searchRequest.SearchTerm.Length));
                        highlightBulder.Append(searchRequest.TagIdentifier);
                        currentIndex += searchRequest.SearchTerm.Length;
                        previousIndex = currentIndex;
                        currentIndex = searchRequest.SearchString.IndexOf(searchRequest.SearchTerm, currentIndex, searchRequest.Comparison);
                    }
                    if (!_helperRequest.TagKeyLookup.ContainsKey(searchRequest.TagIdentifier) &&
                        !string.IsNullOrEmpty(spanValue))
                    {
                        _helperRequest.TagKeyLookup.Add(searchRequest.TagIdentifier, spanValue);
                    }
                    highlightBulder.Append(searchRequest.SearchString.Substring(previousIndex));
                }
                return highlightBulder.ToString();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    private static char[] _characterLookup = null;
        public char[] CharacterLookup
        {
            get
            {
                if (_characterLookup == null)
                {
                    _characterLookup = new char[36];
    
                    lock (_characterLookup)
                    {
                        int indexer = 0;
                        //build the table.
                        for (char c = '0'; c <= '9'; c++) _characterLookup[indexer++] = c;
                        for (char c = 'A'; c <= 'Z'; c++) _characterLookup[indexer++] = c;
                    }
                }
                return _characterLookup;
            }
        }
    

** Краткое изложение процедур:

  • Поиск по термину и применение тегов.
  • Храните уникальные теги в хеш-таблице.
  • Заменить теги с выделением интервала. **
...