windows C#读取字符串中的多个标记

wgxvkvu9  于 2023-01-06  发布在  Windows
关注(0)|答案(2)|浏览(155)

我想允许用户读取字符串中的多个标记。到目前为止,用户只能添加一个标记

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 [b]World[/b] Meet the [i]Programmer[/i]"

输出将如下所示:
“你好世界认识[i]程序员[/i]”
如何从一个字符串中读取多个标签?例如,在一个字符串中,如果我有2 [B][/b]个标签,5 [i][/i]个标签,甚至混合标签([b][i][/i][/b])?

watbbzwu

watbbzwu1#

两个问题:

    • 1.正则表达式的贪婪匹配语义**

\[b\](.*)\[/b\]在字符串中查找最长的匹配项,即greedy。在示例中,您希望它匹配[b]World[/b],但实际上它匹配[b]World[/b] Meet the [b]Programmer[/b](因此也将"Meet the"设置为粗体)。这可以使用non-greedy语法轻松解决:\[b\](.*?)\[/b\](注意额外的?
详细信息:How to Match with Regex "shortest match" in .NET

    • 2.您只需要查找一个标签!**

显然,你的代码只会突出显示一个[b]/[i]标签。如果你想在字符串中包含[b]时处理[i],不要使用else if。如果你想处理所有出现的正则表达式,而不仅仅是第一个,可以使用循环和Regex.Matches

gcxthw6b

gcxthw6b2#

没有正则表达式,但仍然必须稍微调整。
测试:

[Test]
public void Text()
{
        string str = "[b]Hello[/b] This is sample text [b] Goodbye [/b]";
        var bold = AllIndexesOf(str, "b").ToArray();
        
        // Assume the IEnumerable 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>
    /// Courtesy 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)

下面是粗体索引的控制台结果:
配对:0|八个
配对:33|四十五
我还没有对所有的边缘情况进行充分的测试。

相关问题