拆分文件名

我有一个文件名:

NewReport-20140423_17255375-BSIQ-2wd28830-841c-4d30-95fd-a57a7aege412.zip 

如何将上述文件名拆分为4个字符串组。

 NewReport 20140423_17255375 BSIQ 2wd28830-841c-4d30-95fd-a57a7aege412.zip 

我试过了:

  string[] strFileTokens = filename.Split(new char[]{'-'} , StringSplitOptions.None); 

但我没有得到上面要求的四个字符串

您可以指定要返回的最大子串数:

 var strFileTokens = filename.Split(new[] { '-' }, 4, StringSplitOptions.None); 

这样可以避免将2wd28830-841c-4d30-95fd-a57a7aege412.zip分成另外的“碎片”。

(另外,您可以删除 StringSplitOptions.None 因为这是默认设置。)


在内部,它在循环内创建一个子字符串数组,它只循环指定的次数(或字符串中可用的最大分隔符数,以较小者为准)。

 for (int i = 0; i < numActualReplaces && currIndex < Length; i++) { splitStrings[arrIndex++] = Substring(currIndex, sepList[i] - currIndex ); currIndex = sepList[i] + ((lengthList == null) ? 1 : lengthList[i]); } 

变量numActualReplaces是您指定的计数或字符串中存在的实际分隔符数的最小值。 (这样,如果你指定一个更大的数字,比如30,但你在字符串中只有7个连字符,你就不会得到exception。实际上,当你没有指定一个数字时,它实际上是使用 Int32.MaxValue 没有你意识到它。)


你更新了你的问题,说你正在使用Silverlight,它没有重载Count 。 这真的很烦人,因为在引擎盖下, string类仍然支持它。 他们只是没有提供传递你自己价值的方法。 它使用硬编码的int.MaxValue

您可以创建自己的方法来恢复所需的function。 我还没有针对所有边缘情况测试此扩展方法,但它确实适用于您的字符串。

 public static class StringSplitExtension { public static string[] SplitByCount(this string input, char[] separator, int count) { if (count < 0) throw new ArgumentOutOfRangeException("count"); if (count == 0) return new string[0]; var numberOfSeparators = input.Count(separator.Contains); var numActualReplaces = Math.Min(count, numberOfSeparators + 1); var splitString = new string[numActualReplaces]; var index = -1; for (var i = 1; i <= numActualReplaces; i++) { var nextIndex = input.IndexOfAny(separator, index + 1); if (nextIndex == -1 || i == numActualReplaces) splitString[i - 1] = input.Substring(index + 1); else splitString[i - 1] = input.Substring(index + 1, nextIndex - index - 1); index = nextIndex; } return splitString; } } 

确保它在UserControl可以访问的地方,然后像这样调用它:

 var strFileTokens = filename.SplitByCount(new[] { '-' }, 4) 

如果你调用带有count参数的Split的重载,它可以工作:

 var myArray = filename.Split(new char[] { '-' }, 4); 

由于您正在使用后续问题中显示的Silverlight,而没有这种过载,我会展示一种不同的方法。 您可以使用LINQ的SkipTake + string.Join来获取一个string

您的示例字符串:

 string filename = "NewReport-20140423_17255375-BSIQ-2wd28830-841c-4d30-95fd-a57a7aege412.zip"; 

包含所有部分的数组:

 string[] allTokens = filename.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries); var firstThreeToken = allTokens.Take(3); // first three var lastTokens = allTokens.Skip(3); // the last part string lastToken = string.Join("-", lastTokens); // last tokens as single string string[] allToken = firstThreeToken.Concat(new[] { lastToken }).ToArray(); 

结果:

 "NewReport" "20140423_17255375" "BSIQ" "2wd28830-841c-4d30-95fd-a57a7aege412.zip" 

您可以使用Regex.Split方法,该方法提供带有计数参数的重载。

在此处输入图像描述

 Regex reg = new Regex( "-" ); string filename = "NewReport-20140423_17255375-BSIQ-2wd28830-841c-4d30-95fd-a57a7aege412.zip"; var parts = reg.Split( filename, 4 ); 

显然你得到的部分更多,因为你文件的最后一部分也包含“ – ”。

解决它的一个简单方法是加入其余部分,如下所示:

 String lastpart = string.Join("-", names, 3, names.Length - 3);