如何找到特定 BBCode 标签的索引位置(正则表达式)
how to find the index positions of particular BBCode tag (Regex)
我有一个字符串,比方说:
[s]AB[/s]23[sb]45[/sb]AB45ABABAB
我想找到所有被包含字母 s 的标签包围的索引,因此包括 [s] 和 [sb]。
函数调用 findIndices("[s]01[/s]23[sb]45[/sb]AB45ABABAB", "s")将 return 列表 [0, 1, 4, 5]。请注意,索引会忽略所有 BBCode。换句话说,它认为第一个 'A' 字符的索引是 0,而不是 3。
如何在 C# 中实现 findIndices。我尝试使用 System.Text.RegularExpressions 但我遇到了麻烦,困难在于找到相对于删除了 BBCode 的字符串的索引。
像这样的正则表达式模式 (?<=[^/]s.?\]).+?(?=\[)
将匹配例如AB
和 45
我们检查(向后看)我们后面是否有 s
和 ]
,但没有 /
,然后匹配字符,直到我们找到 [=16] =].可能有一些我遗漏的边缘情况,所以请谨慎行事并进行测试。
(如果您特别需要索引,可以从正则表达式匹配对象中获取)
这只是一个例子,你可以这样试试,在这里测试:http://rextester.com/FMTZ35054
public class Entity
{
public string Text {get; set;}
public int Index {get; set;}
public int CountDirty {get; set;}
public int CountClean {get; set;}
public int CountGross {get; set;}
public int IndexStart {get; set;}
public int IndexEnd {get; set;}
public int IndexStartClean {get; set;}
public int IndexEndClean {get; set;}
public int IndexStartGross {get; set;}
public int IndexEndGross {get; set;}
public int CountBefore {get;set;}
public int CountAfter {get;set;}
}
public static List<Entity> findIndices(string text)
{
string regex = @"(\[[a-zA-Z]*\])(.*?)(\[/[[a-zA-Z]*\])";
Regex r = new Regex(regex);
MatchCollection matches = r.Matches(text);
List<Entity> list = new List<Entity>();
int accumulation = 0;
foreach (Match match in matches)
{
Entity t = new Entity();
string stringa2 = match.ToString();
t.CountBefore = match.Groups[1].ToString().Count();
t.CountAfter = match.Groups[3].ToString().Count();
t.CountClean = match.Groups[2].ToString().Count();
t.CountGross = match.ToString().Count();
t.CountDirty = t.CountClean - t.CountGross;
t.Text = stringa2;
t.IndexStart = match.Index;
t.IndexEnd = match.Index + t.CountGross - 1;
t.IndexStartGross = t.IndexStart + t.CountBefore;
t.IndexEndGross = t.IndexStartGross + t.CountClean - 1;
t.IndexStartClean = t.IndexStartGross - t.CountBefore - accumulation;
t.IndexEndClean = t.IndexStartClean + t.CountClean - 1;
list.Add(t);
accumulation += t.CountBefore + t.CountAfter;
}
return list;
}
这是一个实现:
List<Entity> list = findIndices("[s]AB[/s]23[sb]45[/sb]AB45ABABAB[a]test[/a]");
for (var i = 0; i < list.Count; i++)
{
var l = list[i];
Console.WriteLine("Text = " + l.Text);
Console.WriteLine("IndexStartClean = " + l.IndexStartClean);
Console.WriteLine("IndexEndClean = " + l.IndexEndClean);
Console.WriteLine("---");
}
我有一个字符串,比方说:
[s]AB[/s]23[sb]45[/sb]AB45ABABAB
我想找到所有被包含字母 s 的标签包围的索引,因此包括 [s] 和 [sb]。
函数调用 findIndices("[s]01[/s]23[sb]45[/sb]AB45ABABAB", "s")将 return 列表 [0, 1, 4, 5]。请注意,索引会忽略所有 BBCode。换句话说,它认为第一个 'A' 字符的索引是 0,而不是 3。
如何在 C# 中实现 findIndices。我尝试使用 System.Text.RegularExpressions 但我遇到了麻烦,困难在于找到相对于删除了 BBCode 的字符串的索引。
像这样的正则表达式模式 (?<=[^/]s.?\]).+?(?=\[)
将匹配例如AB
和 45
我们检查(向后看)我们后面是否有 s
和 ]
,但没有 /
,然后匹配字符,直到我们找到 [=16] =].可能有一些我遗漏的边缘情况,所以请谨慎行事并进行测试。
(如果您特别需要索引,可以从正则表达式匹配对象中获取)
这只是一个例子,你可以这样试试,在这里测试:http://rextester.com/FMTZ35054
public class Entity
{
public string Text {get; set;}
public int Index {get; set;}
public int CountDirty {get; set;}
public int CountClean {get; set;}
public int CountGross {get; set;}
public int IndexStart {get; set;}
public int IndexEnd {get; set;}
public int IndexStartClean {get; set;}
public int IndexEndClean {get; set;}
public int IndexStartGross {get; set;}
public int IndexEndGross {get; set;}
public int CountBefore {get;set;}
public int CountAfter {get;set;}
}
public static List<Entity> findIndices(string text)
{
string regex = @"(\[[a-zA-Z]*\])(.*?)(\[/[[a-zA-Z]*\])";
Regex r = new Regex(regex);
MatchCollection matches = r.Matches(text);
List<Entity> list = new List<Entity>();
int accumulation = 0;
foreach (Match match in matches)
{
Entity t = new Entity();
string stringa2 = match.ToString();
t.CountBefore = match.Groups[1].ToString().Count();
t.CountAfter = match.Groups[3].ToString().Count();
t.CountClean = match.Groups[2].ToString().Count();
t.CountGross = match.ToString().Count();
t.CountDirty = t.CountClean - t.CountGross;
t.Text = stringa2;
t.IndexStart = match.Index;
t.IndexEnd = match.Index + t.CountGross - 1;
t.IndexStartGross = t.IndexStart + t.CountBefore;
t.IndexEndGross = t.IndexStartGross + t.CountClean - 1;
t.IndexStartClean = t.IndexStartGross - t.CountBefore - accumulation;
t.IndexEndClean = t.IndexStartClean + t.CountClean - 1;
list.Add(t);
accumulation += t.CountBefore + t.CountAfter;
}
return list;
}
这是一个实现:
List<Entity> list = findIndices("[s]AB[/s]23[sb]45[/sb]AB45ABABAB[a]test[/a]");
for (var i = 0; i < list.Count; i++)
{
var l = list[i];
Console.WriteLine("Text = " + l.Text);
Console.WriteLine("IndexStartClean = " + l.IndexStartClean);
Console.WriteLine("IndexEndClean = " + l.IndexEndClean);
Console.WriteLine("---");
}