捕获组,每行捕获多个组

本文关键字: | 更新日期: 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.JoinCaptureCollection的方法。

这基本上是在做什么:

模式@"(?:<!([^<>]+)!>)+(.+)"匹配一个或多个<!...!>"标记",然后匹配该行的其余部分。在此过程中,它捕获<!...!>的内容。每次重复都会记录另一个捕获,您可以稍后在回调中访问它们。在<!...!>标记之后,我们用(.+)匹配并捕获该行的其余部分。注意字符串前面的@:它使字符串逐字生成,在指定regex模式时应该始终这样做-否则在转义时会遇到问题。还要注意,?:在第一个左括号之后。这是为了抑制捕获,因为我们不需要另一个包含分隔符<!!>的捕获。总是使用非捕获组,除非你真的需要捕获,这也是一个很好的实践。

然后,对于输入中的每个匹配项,都会调用回调函数。只有一个匹配包含整行。该匹配捕获了1组中的两个令牌和2组中的其余行。

所以我们现在可以简单地构建一个字符串,从<span ="开始,然后是一个以空格分隔的1组捕获的所有列表,然后是">,然后是捕获的其余行,最后是结束的</span>

正如我所说,如果您找到一种方法来String.Join集合组,回调函数将减少到三行左右。

如果Match, GroupCapture之间的区别对你来说仍然有点模糊,我建议在回调函数中设置一个断点,然后检查那里的match对象。

我无法在RegexHero中重现您的问题:

http://www.regexhero.net/tester

将两个组捕获为:

1: C43
1: TG

你确定你的输入是你所期望的吗?您是否对结果的预期集合进行迭代?

相关文章:
  • 没有找到相关文章