C#:在两个不同的分隔符之间获取子串

时间:2013-09-12 14:37:09

标签: c# regex split

我在拆分这条线时遇到了问题。我想在“@VAR”之间获取每个字符串和“@ENDVAR;”。所以在最后,应该有一个输出:

Variable=Speed;Value=Fast;
Variable=Fabricator;Value=Freescale;Op==;

稍后我将使用“;”分隔每个子串。作为一个分隔符,但我想不会那么难。这是一条线的样子:

@VAR;Variable=Speed;Value=Fast;Op==;@ENDVAR;@VAR;Variable=Fabricator;Value=Freescale;Op==;@ENDVAR;

我尝试了一些分割选项,但大多数时候我只得到一个空字符串。我也试过一个正则表达式。但要么正则表达式错了,要么它不适合我的字符串。可能是错的,在学校我们学习了Regex与C#中使用的不同,所以我在实施时感到困惑。

Regex.Match(t, @"/@VAR([a-z=a-z]*)/@ENDVAR")

修改:

一个小问题:我正在迭代许多行,如问题中的那一行。我在线上使用NoIdeas代码来获得它的形状。下一步是将其打印为文本文件。要打印一个数组,我必须循环它。但是在每次迭代中,当我得到一个新行时,我用当前的splitted字符串覆盖Array。我将其余的代码放在问题中,如果有人可以帮助我会很好。

string[] w ;
foreach (EA.Element theObjects in myPackageObject.Elements)
{
   theObjects.Type = "Object";
   foreach (EA.Element theElements in PackageHW.Elements)
   {
       if (theObjects.ClassfierID == theElements.ElementID)
       {
          t = theObjects.RunState;
          w = t.Replace("@ENDVAR;", "@VAR;").Replace("@VAR;", ";").Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

          foreach (string s in w)
          {
             tw2.WriteLine(s);
          }
       }
   }
}

带有foreach循环的部分非常肯定。我需要一些东西来打印每个分裂的t。提前谢谢。

7 个答案:

答案 0 :(得分:4)

你可以使用

进行正则表达式
str.Replace("@ENDVAR;", "@VAR;")
  .Split(new string[] { "@VAR;" }, StringSplitOptions.RemoveEmptyEntries);

如果你想节省时间,你可以这样做:

str.Replace("@ENDVAR;", "@VAR;")
  .Replace("@VAR;", ";")
  .Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

答案 1 :(得分:3)

你可以在这里使用前瞻断言。

@VAR;(.*?)(?=@ENDVAR)

如果您的字符串永远不会包含@VAR;@ENDVAR;之间的空格,则可以使用以下行,这将与您的行的空实例不匹配。

@VAR;([^\s]+)(?=@ENDVAR)

请参阅此demo

答案 2 :(得分:2)

使用原始字符串操作进行回答。

IEnumerable<string> StuffFoundInside(string biggerString)
{
    var closeDelimeterIndex = 0;
    do
    {
        int openDelimeterIndex = biggerString.IndexOf("@VAR;", startingIndex);
        if (openDelimeterIndex != -1)
        {
            closeDelimeterIndex = biggerString.IndexOf("@ENDVAR;", openDelimeterIndex);
            if (closeDelimiterIndex != -1)
            {
                yield return biggerString.Substring(openDelimeterIndex, closeDelimeterIndex - openDelimiterIndex);
            }
        }    
    } while (closeDelimeterIndex != -1);
}

制作列表并将每个项目添加到列表然后返回列表可能会更快,具体取决于使用此代码的代码如何工作。这允许它提前终止,但具有协程开销。

答案 3 :(得分:1)

使用此正则表达式:

(?i)@VAR;(.+?)@ENDVAR;

每场比赛中的第1组将是您的线路内容。

答案 4 :(得分:1)

  

我尝试了一些分割选项,但大多数时候我只得到一个空字符串。

在这种情况下,要求似乎比你说的要简单。简单地拆分和使用linq将在一个语句中完成整个操作:

        string test = "@VAR;Variable=Speed;Value=Fast;Op==;@ENDVAR;@VAR;Variable=Fabricator;Value=Freescale;Op==;@ENDVAR;";

        List<List<string>> strings = (from s in test.Split(new string[]{"@VAR;",";@ENDVAR;"},StringSplitOptions.RemoveEmptyEntries)
                                let s1 = s.Split(new char[]{';'},StringSplitOptions.RemoveEmptyEntries).ToList<string>()
                                select (s1)).ToList<List<string>>();

outpout是:

?strings[0]
Count = 3
    [0]: "Variable=Speed"
    [1]: "Value=Fast"
    [2]: "Op=="
?strings[1]
Count = 3
    [0]: "Variable=Fabricator"
    [1]: "Value=Freescale"
    [2]: "Op=="

要将数据写入文件,可以使用以下内容:

        foreach (List<string> s in strings)
        {
            System.IO.File.AppendAllLines("textfile1.txt", s);
        }

答案 5 :(得分:1)

(如果你不喜欢正则表达式)

代码:

var s = "@VAR;Variable=Speed;Value=Fast;Op==;@ENDVAR;@VAR;Variable=Fabricator;Value=Freescale;Op==;@ENDVAR;";
var tokens = s.Split(new String [] {"@ENDVAR;@VAR;"}, StringSplitOptions.None);

foreach (var t in tokens)
{
  var st = t.Replace("@VAR;", "").Replace("@ENDVAR;", "");
  Console.WriteLine(st);
}

输出:

Variable=Speed;Value=Fast;Op==;
Variable=Fabricator;Value=Freescale;Op==;

答案 6 :(得分:1)

Regex.Split效果很好,但会产生必须删除的空条目,如下所示:

string[] result = Regex.Split(input, @"@\w+;")
    .Where(s => s != "")
    .ToArray();
相关问题