Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#读取字符串中的多个标记_C#_Windows_Forms - Fatal编程技术网

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

C#读取字符串中的多个标记,c#,windows,forms,C#,Windows,Forms,我希望允许用户读取字符串中的多个标记。到目前为止,用户只能添加一个标签 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.IndexO

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

 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]"
输出如下所示:

“你好世界程序员见面会”

如果我有这个字符串:

"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])?

两个问题:

1。正则表达式的贪婪匹配语义

\[b\](.*)\[/b\]
在字符串中查找最长的可能匹配项,即它是贪婪的。在您的示例中,您希望它与
[b]World[/b]
匹配,而实际上它与
[b]World[/b]与[b]Programmer[/b]
匹配(因此将“Meet the”也设为粗体)。这可以使用非贪婪语法轻松解决:
\[b\](.*?\[/b\]
(注意额外的

详情:

2。您只查找一个出现的标记


显然,您的代码将只突出显示一个
[b]
/
[i]
标记。如果要在字符串包含
[b]
时处理
[i]
,请不要使用
else if
。如果要处理正则表达式的所有匹配项,而不仅仅是第一个,请使用循环和
Regex.Matches

不使用Regex,但仍必须稍微调整

测试:

[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
      }
[测试]
公共无效文本()
{
string str=“[b]你好[/b]这是示例文本[b]再见[/b]”;
var bold=allindexosf(str,“b”).ToArray();
//假设Ienumberable甚至是它应该抛出的错误
对于(int i=0;i
这里是方法

    /// <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
    }
}
//
///礼貌:http://stackoverflow.com/a/24016130/5282506
///由我改编。
/// 
///传入唯一符号并找到第一个和最后一个索引对
///可以适应一次找到所有唯一对。
/// 
///绳子。
///搜索字符串字母(b、i等)
/// 
公共静态IEnumerable AllIndexesOf(字符串str、字符串searchstring)
{
//假定字符串格式正确。每个标记内只有一个相同类型的标记。
int minIndex=str.IndexOf(“[”+searchstring+“]”);
而(minIndex!=-1)
{
WriteLine(“第一个:{0}”,minIndex);
收益率最小指数;
var maxIndexEnd=str.IndexOf(“[/”+searchstring+“]”),minIndex+searchstring.Length+3);//为[/and]字符添加了三个。
WriteLine(“End:{0}”,maxIndexEnd);
如果(maxIndexEnd==-1)
{
//字符串格式错误,找不到起始元素的结束元素
//做点什么。。。
抛出新的FormatException(“格式错误的字符串”);
}
收益返回maxIndexEnd;
minIndex=str.IndexOf(“[”+searchstring+“]”),maxIndexEnd+searchstring.Length+2);//为[and]字符添加了两个
}
}
如果希望将其作为字符串更改签名的扩展方法,请执行以下操作:

public static IEnumerable<int> AllIndexesOf(this string str, string searchstring)
公共静态IEnumerable allindexosf(此字符串str,字符串searchstring)
以下是粗体索引的控制台结果:

配对:0 | 8

配对:33 | 45

我还没有对所有边缘情况完全测试此方法