我想允许用户这样他们可以在字符串中读取多个标签。到目前为止,用户只能添加一个标签
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]),在字符串中?
答案 0 :(得分:3)
两个问题:
<强> 1。正则表达式的贪婪匹配语义
\[b\](.*)\[/b\]
在您的字符串中查找最长可能匹配,即贪婪。在您的示例中,您希望它与[b]World[/b]
匹配,而实际上它与[b]World[/b] Meet the [b]Programmer[/b]
匹配(因此也会使“Meet the”加粗)。这可以使用非贪婪语法轻松解决:\[b\](.*?)\[/b\]
(请注意额外的?
)
详细信息:How to Match with Regex "shortest match" in .NET
<强> 2。您只需查找一次标记!
显然,您的代码只会突出显示一个[b]
/ [i]
代码。如果您希望在字符串包含else if
时处理[i]
,请不要使用[b]
。如果要处理所有正则表达式而不是第一个正则表达式,请使用循环和Regex.Matches
。
答案 1 :(得分: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)
下面是粗体索引的控制台结果:
配对:0 | 8
配对:33 | 45
我还没有针对所有边缘情况对此方法进行全面测试。