c#在字符串中读取多个标签
本文关键字:标签 读取 字符串 | 更新日期: 2023-09-27 18:10:23
我想允许用户在字符串中读取多个标记。到目前为止,用户只能添加一个标签
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 Meet the Programmer"
如果我有这个字符串:
"Hello [b]World[/b] Meet the [i]Programmer[/i]"
的输出是这样的:
世界"你好满足(我)程序员[/i]"
如何从一个字符串读取多个标签?比如,在一个字符串中,如果我有2个[b][/b]标签,5个[I][/I]标签,甚至混合标签([b][I][/I][/b])?
两个问题:
1。正则表达式
的贪婪匹配语义 '[b'](.*)'[/b']
在字符串中查找最长的可能匹配,即它是贪婪的。在您的示例中,您期望它匹配[b]World[/b]
,而实际上它匹配[b]World[/b] Meet the [b]Programmer[/b]
(因此使"Meet the"也成为粗体)。这可以很容易地使用非贪婪语法解决:'[b'](.*?)'[/b']
(注意额外的?
)
详细信息:如何匹配Regex "最短匹配"在。net
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 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
}
}
如果您希望将其作为字符串的扩展方法,请将签名更改为this:
public static IEnumerable<int> AllIndexesOf(this string str, string searchstring)
下面是粗体索引的控制台结果:
Pair: 0 | 8
Pair: 33 | 45
我还没有对所有的边缘情况完全测试这个方法。