我有一些带有'控制序列'的html,我已经从内容中删除了html标签,现在我想将'控制序列'变成'样式'。
删除html标签后我就有了......
"<!C43!><!TG!>Some Characters"
最终产生这个...
<span class="C43 TG">Some Characters</span>
到目前为止我的错误c#:
Regex reg = new Regex("<!([^<>]+?)!>");
Match matches = reg.Match(line);
foreach (Group group in matches.Groups)
{
// finds both groups,
// and remove the control sequence
}
我的'foreach'还没有多少,因为当我用breakboint检查它时,它会错误地返回以下组...
Group 1 : <!C43!>
Group 2 : C43
<it does not find second group :( >
任何帮助都会受到赞赏,但我主要是寻找正确的正则表达式来找到我在字符串中寻找的内容,但我对正则表达式库也没用,所以最有效的'查找组,商店组,从字符串中删除组我正在搜索'也将非常感激。
答案 0 :(得分:3)
你正在循环错误的事情。试试这个:
string line = ...;
Regex reg = ...;
for (var match = reg.Match(line); match.Success; match = match.NextMatch())
{
// in here, don't bother with .Groups... you don't need it
}
答案 1 :(得分:2)
正如其他人所说,由于您的模式只有一个组,因此您希望循环Match
而不是Group
s。通常的方法是Michael Gunter的for
循环或简单地
Match m = reg.Match(line);
while(m.Success)
{
// read class from m.Groups[1]
m = m.NextMatch();
}
然而,为了解决你的最终问题,单独取出所有数据并将字符串重新组合在一起可能会有点烦人 - 特别是如果你想一次在多行中进行这种替换。
因此,您可能希望查看Regex.Replace
(采用回调的版本)。这样,您就可以在一次匹配中匹配所有内容,然后利用.NET的独特功能访问单个组的多个捕获。
var line = "<!C43!><!TG!>Some Characters";
MatchEvaluator evaluator = new MatchEvaluator(ReplaceCallback);
string output = Regex.Replace(
line,
@"(?:<!([^<>]+)!>)+(.+)",
evaluator
);
你班上的其他地方:
static string ReplaceCallback(Match match)
{
var sb = new StringBuilder("<span class=\"");
sb.Append(match.Groups[1].Captures[0].Value);
for(int i = 1; i < match.Groups[1].Captures.Count; i++)
{
sb.Append(" ");
sb.Append(match.Groups[1].Captures[i].Value);
}
sb.Append("\">");
sb.Append(match.Groups[2].Value);
sb.Append("</span>");
return sb.ToString();
}
使用String.Format
设置字符串可能会更容易,但我找不到String.Join
CaptureCollection
的方法。
那么这基本上是做什么的:
模式@"(?:<!([^<>]+)!>)+(.+)"
匹配一个或多个<!...!>
“标记”,然后是该行的其余部分。这样做时它会捕获<!...!>
的内容。在每次重复时,都会记录另一次捕获,您可以在回调中稍后访问它们。在<!...!>
令牌之后,我们匹配并使用(.+)
捕获该行的其余部分。请注意字符串前面的@
:它会逐字地生成字符串,在指定正则表达式模式时应始终这样做 - 否则在转义时会遇到问题。另请注意第一个左括号后的?:
。这是为了抑制捕获,因为我们不需要另外包含分隔符<!
和!>
的捕获。除非您确实需要捕获,否则始终使用非捕获组也是一种很好的做法。
然后为输入中的每个匹配调用回调函数。只有一个匹配包含整行。该匹配已捕获组1
中的两个令牌以及组2
中的其余行。
因此,我们现在可以简单地构建一个以<span ="
开头的字符串,然后是一个以空格分隔的列表,其中列出了1
组的所有捕获,然后是">
,然后是捕获的剩余部分该行,最后是结束</span>
。
正如我所说,如果你找到了String.Join
收集组的方法,回调函数会减少到三行左右。
如果Match
,Group
和Capture
之间的区别对您来说仍然有点模糊,我建议在回调函数中设置一个断点,然后检查match
对象那里。
答案 2 :(得分:0)
我无法在RegexHero中重现您的问题:
http://www.regexhero.net/tester
它将两组捕获为:
1: C43
1: TG
您确定您的输入是您所期望的吗?您是否在结果的预期集合上进行迭代?