【问题标题】:Getting a list of strings by splitting a string by a specific tag通过按特定标签拆分字符串来获取字符串列表
【发布时间】:2018-12-31 18:40:20
【问题描述】:

我想通过特定标签将字符串拆分为列表或数组。

<START><A>message<B>UnknownLengthOfText<BEOF><AEOF><A>message<B>UnknownLengthOfText<BEOF><AEOF><END>

我想把上面的例子分成两个项目,项目是&lt;A&gt;&lt;AEOF&gt;标签之间的字符串

感谢任何帮助。

【问题讨论】:

  • 这看起来有点像 XML。是 GML 还是别的什么?
  • 那太没用了。我想知道它是否是已知格式。

标签: c# arrays string split


【解决方案1】:

我建议为此使用简单的正则表达式。 看看这个例子:

using System.Diagnostics;
using System.Text.RegularExpressions;

...

Regex regex = new Regex("<A>(.*?)<B><BEOF>(.*?)<AEOF>");
string myString = @"<START><A>message<B><BEOF>UnknownLengthOfText<AEOF><A>message<B><BEOF>some other line of text<AEOF><END>";
MatchCollection matches = regex.Matches(myString);
foreach (Match m in matches)
{
    Debug.WriteLine(m.Groups[1].ToString(), m.Groups[2].ToString());
}

编辑:

由于字符串在一行,正则表达式应该是“惰性的”,用惰性量词? 标记。另外,我更改了正则表达式,以便它使用 sTrenat 的建议来自动解析消息和标题。

所以,而不是

Regex regex = new Regex("<A>(.*)<AEOF>");

我用过

Regex regex = new Regex("<A>(.*?)<B><BEOF>(.*?)<AEOF>");

注意额外的?标记惰性量词,当它找到标签之间的第一个匹配时停止(没有?整个字符串将被捕获,而不是标签之间的n消息)

【讨论】:

【解决方案2】:

试试这样的:

string test = @"<START>
                   <A>message<B><BEOF>UnknownLengthOfText<AEOF>
                   <A>message<B><BEOF>UnknownLengthOfText<AEOF>
                <END>";

//for this test this will give u an array containing 3 items...
string[] tmp1 = test.Split("<AEOF>");

//here u will store your results in
List<string> results = new List<string>();

//for every single one of those 3 items:
foreach(string item in tmp1)
{
     //this will only be true for the first and second item
     if(item.Contains("<A>"))
     {
           string[] tmp2 = item.Split("<A>");

           //As the string you are looking for is always BEHIND the <A> you 
           //store the item[1], (the item[0] would be in front)

           results.Add(tmp2[1]);
     }
}

【讨论】:

    【解决方案3】:

    您可以使用 Regex.Split 而不是使用 String.Split,如下所示

            var stringToSplit = @"<START>
                                    <A>message<B>UnknownLengthOfText<BEOF><AEOF>
                                    <A>message<B>UnknownLengthOfText<BEOF><AEOF>
                                <END>";
    
            var regex = "<A>(.*)<AEOF>";
            var splitStrings = Regex.Split(stringToSplit, regex);
    

    splitStrings 将包含 4 个元素

    splitString[0] = "<START>"
    splitString[1] = "message<B>UnknownLengthOfText<BEOF>"
    splitString[2] = "message<B>UnknownLengthOfText<BEOF>"
    splitString[3] = "<END>"
    

    使用正则表达式只能给你和之间的字符串

    【讨论】:

      【解决方案4】:

      到目前为止,所有答案都是基于正则表达式的。这是一个没有的替代方案:

      Try it Online!

          var input = @"
      <START>
          <A>message<B>UnknownLengthOfText<BEOF><AEOF>
          <A>message<B>UnknownLengthOfText<BEOF><AEOF>
      <END>";
          var start = "<A>";
          var end = "<AEOF>";
          foreach (var item in ExtractEach(input, start, end))
          {
              Console.WriteLine(item);
          }
      }
      
      public static IEnumerable<string> ExtractEach(string input, string start, string end)
      {
          foreach (var line in input
                   .Split(Environment.NewLine.ToCharArray())
                   .Where(x=> x.IndexOf(start) > 0 && x.IndexOf(start) < x.IndexOf(end)))
          {
              yield return Extract(line, start, end);
          }
      }
      
      
      public static string Extract(string input, string start, string end)
      {
          int startPosition = input.LastIndexOf(start) + start.Length;
          int length = input.IndexOf(end) - startPosition;
          var substring = input.Substring(startPosition, length);
          return substring;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-18
        • 2018-05-16
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多