捕获组,每行捕获多个组
本文关键字: | 更新日期: 2023-09-27 18:17:11
我有一些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'中得到太多,因为当我用断点检查它时,它错误地返回以下组…
Group 1 : <!C43!>
Group 2 : C43
<it does not find second group :( >
任何帮助将不胜感激,但我主要是寻找正确的正则表达式来找到我在字符串中寻找的东西,但我也没用正则表达式库,所以最有效的'查找组,存储组,从字符串中删除组我正在搜索'也将非常感激。
你在错误的东西上循环。试试这个:
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
}
正如其他人所说,您希望遍历Match
es而不是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
的方法。
这基本上是在做什么:
模式@"(?:<!([^<>]+)!>)+(.+)"
匹配一个或多个<!...!>
"标记",然后匹配该行的其余部分。在此过程中,它捕获<!...!>
的内容。每次重复都会记录另一个捕获,您可以稍后在回调中访问它们。在<!...!>
标记之后,我们用(.+)
匹配并捕获该行的其余部分。注意字符串前面的@
:它使字符串逐字生成,在指定regex模式时应该始终这样做-否则在转义时会遇到问题。还要注意,?:
在第一个左括号之后。这是为了抑制捕获,因为我们不需要另一个包含分隔符<!
和!>
的捕获。总是使用非捕获组,除非你真的需要捕获,这也是一个很好的实践。
1
组中的两个令牌和2
组中的其余行。
所以我们现在可以简单地构建一个字符串,从<span ="
开始,然后是一个以空格分隔的1
组捕获的所有列表,然后是">
,然后是捕获的其余行,最后是结束的</span>
。
正如我所说,如果您找到一种方法来String.Join
集合组,回调函数将减少到三行左右。
如果Match
, Group
和Capture
之间的区别对你来说仍然有点模糊,我建议在回调函数中设置一个断点,然后检查那里的match
对象。
我无法在RegexHero中重现您的问题:
http://www.regexhero.net/tester将两个组捕获为:
1: C43
1: TG
你确定你的输入是你所期望的吗?您是否对结果的预期集合进行迭代?