2012-06-22 2 views
0

процедуру поиска с помощью полнотекстового поиска (это означает: трудно воспроизвести матч за пределами процедуры) возвращают строки, освещающие найденную строку внутри, как:получить подстроку сохранения HTML тега внутри

"i have been <em>match</em>ed" 
"a <em>match</em> will happen in the word <em>match</em>" 
"some random words including the word <em>match</em> here" 

Сейчас я нужно получить первые x символов строки, но я получаю несколько неприятностей с тегами html внутри.

Как:

"i have been <em>mat</em>..." -> first 15 characters 
"a <em>match</em> will happen in the word <em>m</em>..." -> first 33 characters 
"some rando..." -> first 10 characters 

Я попытался с помощью некоторых, если еще, но я в конечном итоге с большими спагетти.

Любые советы?

+0

Существуют ли только те теги - i.e., остальные тексты? –

+0

@EugenRieck да. Все, кроме обычного текста, разрешено пользователю. – user1330271

+0

@EugenRieck Извините, не разрешено пользователю! – user1330271

ответ

1

Это должно делать то, что вы хотите, основываясь только на тегах <em>.

using System; 
using System.Collections.Generic; 
using System.Text; 

namespace Test 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var dbResults = GetMatches(); 
      var firstLine = HtmlSubstring(dbResults[0], 0, 15); 
      Console.WriteLine(firstLine); 
      var secondLine = HtmlSubstring(dbResults[1], 0, 33); 
      Console.WriteLine(secondLine); 
      var thirdLine = HtmlSubstring(dbResults[2], 0, 10); 
      Console.WriteLine(thirdLine); 

      Console.Read(); 
     } 

     private static List<string> GetMatches() 
     { 
      return new List<string> 
      { 
       "i have been <em>match</em>ed" 
       ,"a <em>match</em> will happen in the word <em>match</em>" 
       , "some random words including the word <em>match</em> here" 
      }; 
     } 

     private static string HtmlSubstring(string mainString, int start, int length = int.MaxValue) 
     { 
      StringBuilder substringResult = new StringBuilder(mainString.Replace("</em>", "").Replace("<em>", "").Substring(start, length)); 

      // Get indexes between start and (start + length) that need highlighting. 
      int matchIndex = mainString.IndexOf("<em>", start); 
      while (matchIndex > 0 && matchIndex < (substringResult.Length - start)) 
      { 
       int matchIndexConverted = matchIndex - start; 
       int matchEndIndex = mainString.IndexOf("</em>", matchIndex) - start; 

       substringResult.Insert(matchIndexConverted, "<em>"); 
       substringResult.Insert(Math.Min(substringResult.Length, matchEndIndex), "</em>"); 

       matchIndex = mainString.IndexOf("<em>", matchIndex + 1); 
      } 

      return substringResult.ToString(); 
     } 
    } 
} 
1

Предлагаю написать простой парсер с несколькими штатами - InText, InOpeningTag, InClosingTag - это некоторые, которые приходят на ум.

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

Посмотрите на исходный код для HTML Agility Pack, если вы не знаете, о чем я говорю (ищите методы Parse).