捕获字符串中的两个块

本文关键字:两个 字符串 | 更新日期: 2023-09-27 18:08:06

我有一个字符串,它的格式是:

消息:这里发生了不好的事情。& lt;描述>这里有一些信息描述& lt;错误>其他一些东西 & lt;消息>这里有消息

我似乎无法弄清楚如何匹配描述块中的所有内容以及使用正则表达式的消息块中的所有内容。

我的问题分为两部分:1)regex是正确的选择吗?2)。如果是这样,我如何匹配这两个块并排除其余的?


我可以用一个简单的<描述>。* & lt;/Description>,但不能匹配<消息>。我试图排除中间的所有内容使用这里描述的http://blog.codinghorror.com/excluding-matches-with-regular-expressions/

捕获字符串中的两个块

尽管有关于用regex解析xml的所有免责声明,但知道如何使用regex解析xml仍然是很好的。

例如,如果你背对着墙,这将适用于< Description>标签(适应其他标签)。

(?<=< Description>).*?(?=< /Description>)

你需要知道的一些事情:

  1. (?<=< Description>)是一个后置,它断言在字符串的那个位置,前面的是< Description>。因此,如果您更改标记中的空格,那么所有的赌注都将取消。要处理潜在的输入错误(取决于文本的来源),可以插入可选的空格:(?<=< *Description *>),其中*重复空格字符0次或多次。向后看只是一个断言,它不消耗任何字符。
  2. .*?懒洋洋地吃掉所有的字符,直到它能找到下面的…
  3. 这是(?=< /Description>)前向,它断言在字符串的那个位置,后面是< /Description>

在代码中,这就变成了:

description = Regex.Match(yourstring, "(?<=< *Description *>).*?(?=< */Description *>)").Value;

我将如何解析它。警告:我在编写正则表达式时假设你提供的示例中显示的格式相当严格;如果数据有一点变化(例如,'<'字符后面并不总是有空格),则需要稍微调整一下。但这应该能让你继续。

var text = "Message: Something bad happened in This.Place < Description> Some"+
           " sort of information here< /Description>< Error> Some other stuff"+
           "< /Error>< Message> Some message here.";
var regex = new Regex(
      "^.*?<''sDescription''>(?<description>.*?)<''s/Description''>"+
      ".*?<''sMessage''>(?<message>.*?)$",
      RegexOptions.IgnoreCase | RegexOptions.Singleline
    );
var matches = regex.Match(text);
if (matches.Success) {
    var desc = matches.Groups["description"].Value;
    // " Some sort of information here"
    var msg = matches.Groups["message"].Value;
    // " Some message here."
}

尝试从文本中删除非xml格式的数据相当困难,因此我最终使用了IndexOf和Substring。IndexOf将查找指定字符或字符串的索引,Substring根据起始点和应该捕获的数量捕获字符。

int descriptionBegin = 0;
int descriptionEnd = 0;
int messageBegin = 0;
int messageEnd = 0;
foreach (string j in errorList)
{
    descriptionBegin = j.IndexOf("<Description>") + 13; // starts after the opening tag
    descriptionEnd = j.IndexOf("</Description>") - 13; // ends before the closing tag
    messageBegin = j.IndexOf("<Message>") + 9; // starts after the opening tag
    messageEnd = j.IndexOf("</Message>") - 9; // ends before the closing tag
    descriptionDiff = descriptionEnd - descriptionBegin; // amount of chars between tags
    messageDiff = messageEnd - messageBegin; // amount of chars between tags
    string description = j.Substring(descriptionBegin, descriptionDiff); // grabs only specified amt of chars
    string message = j.Substring(messageBegin, messageDiff); // grabs only specified amt of chars
}

感谢@Lucius的建议。@Darryl这看起来真的可行。谢谢你彻底的回答…以后我可能会在其他东西上尝试这种方法(当然非xml:))