【问题标题】:Regex to capture tagged and untagged content正则表达式捕获标记和未标记的内容
【发布时间】:2016-12-20 19:51:56
【问题描述】:

我想要做的是从字符串中解析一些自定义标签,同时也获取未标记的内容。例如,我有以下字符串

Hello World <Red>This is some red text </Red> This is normal <Blue>This is blue text </Blue>

我有一个有效的正则表达式,用于使用

获取标记的内容
<(?<tag>\w*)>(?<text>.*)</\k<tag>>

但是,这会返回

 tag: Red
 text: This is some red text
 tag: Blue
 text this is blue text

我还需要获取未标记内容的匹配项,所以我会得到 4 个匹配项,两个像上面一样,还有“Hello World”和“This is normal”。

这是否可以通过正则表达式实现?

例如,这是我当前的功能:

 public static List<FormattedConsole> FormatColour(string input)
    {
        List<FormattedConsole> formatted = new List<FormattedConsole>();
        Regex regex = new Regex("<(?<Tag>\\w+)>(?<Text>.*?)</\\1>", RegexOptions.IgnoreCase
                | RegexOptions.CultureInvariant
                | RegexOptions.IgnorePatternWhitespace
                | RegexOptions.Compiled
        );

        MatchCollection ms = regex.Matches(input);

        foreach (Match match in ms)
        {
            GroupCollection groups = match.Groups;
            FormattedConsole format = new FormattedConsole(groups["Text"].Value, groups["Tag"].Value);
            formatted.Add(format);
        }

        return formatted;
    }

如前所述,这只返回标签之间的匹配项。我还需要获取没有标签的文本。

(顺便说一句,FormattedConsole 只是一个包含文本和颜色的容器)

【问题讨论】:

  • 这与 WPF 有什么关系?
  • 输入的是 XML 还是只是看起来像 XML?
  • @Clemens 对不起,我的错,我习惯于标记为 WPF,因为我的很多问题需要不同的答案,因为我在 WPF 中工作。习惯的力量。
  • @AlexK.它看起来像 xml,它实际上只是一个从 lua 脚本发送到 c# 函数的字符串。允许我为一些输出着色

标签: c# regex


【解决方案1】:

你可以试试这个:

string sentence = "Hello World <Red>This is some red text </Red> This is normal <Blue>This is blue text </Blue>";
string[] matchSegments = Regex.Split(sentence,@"(<\w+>)(.*?)<\/\w+>");
foreach (string value in matchSegments)
{
    if(value.Contains("<") && value.Contains(">"))
        Console.Write(value);
    else
        Console.WriteLine(value);   
}

输出:

Hello World
<Red>This is some red text
 This is normal
<Blue>This is blue text

Run the code here

【讨论】:

  • 感谢您的回复。我想我可以使用它,然后在包含标签的行上运行第二个正则表达式以从中提取颜色。我会试试这个。谢谢。
  • 去掉角度会产生颜色,只要去掉里面的 if condition ... 就可以了
  • 或者@"&lt;(\w+)&gt;(.*?)&lt;/\w+&gt;" 会产生更清晰的结果。甚至@"&lt;(\w+)&gt;(.*?)&lt;/\1&gt;"
  • 是的,首先我是这样做的,然后我实际上不知道 op 将如何需要答案,我猜它可以根据 op 的需要即时完成
  • 如果您使用索引增量循环遍历数组并看到该值包含尖括号,那么您也可以通过再次增加索引来立即获取文本......这应该很简单。此外,我故意保留尖括号,否则循环时你不知道文本和标签之间的区别
【解决方案2】:

如果您想尝试修改 xml,您可以尝试类似这样的解决方案。我们将使用 Linq。在线试用:https://dotnetfiddle.net/J4zVMY

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

public class Program
{   
    public static void Main()
    {
        string response = @"Hello World <Red>This is some red text </Red> This is normal <Blue>This is blue text </Blue>";
        response = @"<?xml version='1.0' encoding='utf-8'?><root>"+response+"</root>";
        var doc = XDocument.Parse(response);

        // fill all node in a list of Text
        var colors = new List<Text>();
        foreach (var hashElement in doc.Descendants().Skip(1).Where(node => !node.IsEmpty))
        {
            var text = GetText(hashElement.PreviousNode);
            if (text != null)
                colors.Add(new Text(text));
            colors.Add(new Text(hashElement.Value.Trim(), hashElement.Name.ToString()));
        }

        // handle trailing content
        var lastText = GetText(doc.Descendants().Last().NextNode);
        if (lastText != null)
            colors.Add(new Text(lastText));

        // print
        foreach (var color in colors)
            Console.WriteLine($"{color.Color}: {color.Content}");
    }

    private static string GetText(XNode node)=> (node as XText)?.Value.Trim();

    public class Text
    {
        public string Content { get; set; }
        public string Color { get; set; }

        public Text(string content, string color = "Black")
        {
            Color = color;
            Content = content;
        }
    }
}

输出

Black: Hello World
Red: This is some red text
Black: This is normal
Blue: This is blue text

警告:欢迎任何帮助。我的 Linq-to-xml 可能有点生疏了。

【讨论】:

  • 您好,感谢您的回复。不幸的是,我正在处理的不是 xml,它只是传递给方法的简单字符串(在这种情况下来自 lua,但我认为这并不重要)
  • @user1412240 你可以很容易地把它变成一个xml:@"&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;root&gt;"+response+"&lt;/root&gt;";
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-21
  • 2014-10-28
相关资源
最近更新 更多