2015-08-30 6 views
1

Я хочу разрешить пользователю, чтобы они могли читать более одного тега в строке. До сих пор, пользователь может добавить только один тегC# Чтение нескольких тегов в строке

if (rtb.Text.Contains("[b]")) 
    { 
     Regex regex = new Regex(@"\[b\](.*)\[/b\]"); 
     var v = regex.Match(rtb.Text); 
     string s = v.Groups[1].ToString(); 

     rtb.SelectionStart = rtb.Text.IndexOf("[b]"); 
     rtb.SelectionLength = s.Length + 7; 

     rtb.SelectionFont = new Font(rtb.Font.FontFamily, rtb.Font.Size, FontStyle.Bold); 
     rtb.SelectedText = s; 
    } 


else if (rtb.Text.Contains("[i]")) 
    { 
     Regex regex = new Regex(@"\[i\](.*)\[/i\]"); 
     var v = regex.Match(rtb.Text); 
     string s = v.Groups[1].ToString(); 

     rtb.SelectionStart = rtb.Text.IndexOf("[b]"); 
     rtb.SelectionLength = s.Length + 7; 

     rtb.SelectionFont = new Font(rtb.Font.FontFamily, rtb.Font.Size, FontStyle.Italic); 
     rtb.SelectedText = s; 
     } 

richTextBox1.Select(richTextBox1.TextLength, 0); 
richTextBox1.SelectedRtf = rtb.Rtf; 

Если у меня есть эта строка:

"Hello [b]World[/b] Meet the [b]Programmer[/b]" 

результат будет выглядеть так:

«Hello World Встретить Программист "

И если у меня есть эта строка:

"Hello [b]World[/b] Meet the [i]Programmer[/i]" 

результат будет выглядеть так:

"Hello World Встречайте [I] Программист [/ i]"

Как читать несколько тегов из строки ? например, в строке, если у меня есть теги [b] [/ b], теги 5 [i] [/ i] или даже смешанные теги ([b] [i] [/ i] [/ b])?

ответ

3

Две проблемы:

1. Жадный соответствия семантика Regex

\[b\](.*)\[/b\] ищет длинного возможного совпадения в вашей строке, то это жадный. В вашем примере вы ожидаете, что он будет соответствовать [b]World[/b], когда на самом деле он соответствует [b]World[/b] Meet the [b]Programmer[/b] (следовательно, сделать «Встретить» также жирным шрифтом). Это может быть легко решено с помощью нежадных синтаксиса: \[b\](.*?)\[/b\] (обратите внимание на дополнительные ?)

Детали: How to Match with Regex "shortest match" in .NET

2. Вы смотрите только одно вхождения тегов!

Очевидно, что ваш код выделит только один тег [b]/[i]. Не используйте else if, если вы хотите, чтобы [i] обрабатывался, если ваша строка содержит [b]. Используйте циклы и Regex.Matches, если вы хотите обрабатывать все вхождения вашего регулярного выражения, а не только первое.

0

Без регулярного выражения, но все еще необходимо немного адаптировать.

Тест:

[Test] 
    public void Text() 
    { 
     string str = "[b]Hello[/b] This is sample text [b] Goodbye [/b]"; 
     var bold = AllIndexesOf(str, "b").ToArray(); 

     //assume the Ienumberable is even else it should of thrown an error 
     for(int i = 0; i < bold.Count(); i += 2) 
     { 
      Console.WriteLine($"Pair: {bold[i]} | {bold[i+1]}"); 
     } 
     //str.AllIndexesOf 
     } 

Вот метод.

/// <summary> 
    /// Courtesty of : http://stackoverflow.com/a/24016130/5282506 
    /// Adapted by me. 
    /// 
    /// Pass in the unique symbol and itll find the first and last index pairs 
    /// Can adapt to find all unique pairs at once. 
    /// </summary> 
    /// <param name="str">The string.</param> 
    /// <param name="searchstring">The searchstring letter (b, i, etc)</param> 
    /// <returns></returns> 
public static IEnumerable<int> AllIndexesOf(string str, string searchstring) 
{ 
    //assumes the string is formatted correctly. Only one tag of the same type inside each tag. 

    int minIndex = str.IndexOf("["+searchstring+"]"); 
    while (minIndex != -1) 
    { 
     Console.WriteLine("First: {0}", minIndex); 
     yield return minIndex; 
     var maxIndexEnd = str.IndexOf("[/"+ searchstring +"]", minIndex + searchstring.Length +3);//added three for the [/ and ] characters. 
     Console.WriteLine("End: {0}", maxIndexEnd); 

     if (maxIndexEnd == -1) 
     { 
      //Malformed string, no end element for a found start element 
      //Do something... 
      throw new FormatException("Malformed string"); 
     } 
     yield return maxIndexEnd; 
     minIndex = str.IndexOf("[" + searchstring+"]", maxIndexEnd + searchstring.Length+2);//added two for the [ and ] characters 
    } 
} 

Если вы хотите, чтобы сделать его метод расширения для изменения строки подписи к этому:

public static IEnumerable<int> AllIndexesOf(this string str, string searchstring) 

Heres результат консоль для смелых индексов:

Pair: 0 | 8

Пара: 33 | 45

Я не полностью протестировал этот метод для всех случаев краев.