简体   繁体   English

拆分文件名

[英]Splitting a filename

I've a filename: 我有一个文件名:

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

How can i split the above filename to 4 string groups. 如何将上述文件名拆分为4个字符串组。

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

I tried: 我试过了:

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

but i'm not getting the above required four strings 但我没有得到上面要求的四个字符串

You can specify the maximum number of substrings to return: 您可以指定要返回的最大子字符串数:

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

This will avoid splitting 2wd28830-841c-4d30-95fd-a57a7aege412.zip into additional "pieces". 这样可以避免将2wd28830-841c-4d30-95fd-a57a7aege412.zip分成另外的“碎片”。

(Also, you can drop StringSplitOptions.None since that's the default.) (此外,您可以删除 StringSplitOptions.None 因为这是默认设置。)


Internally, it creates an array of substrings inside a loop, and it only loops the number of times you specify (or the maximum number of delimiters available in your string, whichever is less). 在内部,它在循环内创建一个子字符串数组,它只循环指定的次数(或字符串中可用的最大分隔符数,以较小者为准)。

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

The variable numActualReplaces is the minimum of either the count you specify, or the number of actual delimiters present in your string. 变量numActualReplaces是您指定的计数或字符串中存在的实际分隔符数的最小值。 (That way, if you specify a larger number like 30, but you only have 7 hyphens in the string, you won't get an exception. Actually, when you don't specify a number at all, it's actually using Int32.MaxValue without you even realizing it.) (这样,如果你指定一个更大的数字,比如30,但你在字符串中只有7个连字符,你将不会得到异常。实际上,当你没有指定一个数字时,它实际上是使用 Int32.MaxValue 没有你意识到它。)


You updated your question to say you're using Silverlight, which doesn't have he overloads with Count . 你更新了你的问题,说你正在使用Silverlight,它没有重载Count That's really annoying, because under the hood the string class still supports it. 这真的很烦人,因为在引擎盖下, string类仍然支持它。 They just didn't provide a way to pass in your own value. 他们只是没有提供传递你自己价值的方法。 It uses a hard-coded int.MaxValue . 它使用硬编码的int.MaxValue

You could create your own method to bring back the desired functionality. 您可以创建自己的方法来恢复所需的功能。 I haven't tested this extension method out for all edge-cases, but it does work with your string. 我还没有针对所有边缘情况测试此扩展方法,但它确实适用于您的字符串。

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;
    }
}

Make sure it's somewhere accessible to your UserControl, then call it like this: 确保它在UserControl可以访问的地方,然后像这样调用它:

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

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

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

Since you're using silverlight as shown in your follow up question which doesn't have this overload i show a different approach. 由于您正在使用后续问题中显示的没有这种过载的Silverlight,因此我展示了一种不同的方法。 You could use LINQ's Skip , Take + string.Join to get one string : 您可以使用LINQ的SkipTake + string.Join来获取一个string

Your sample string: 您的示例字符串:

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

An array with all parts: 包含所有部分的数组:

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();

Result: 结果:

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

You can use the Regex.Split method which offers an overload that takes the count param. 您可以使用Regex.Split方法,该方法提供带有计数参数的重载。

在此输入图像描述

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

Obviously you are getting more parts because the last part of your file also contains "-". 显然你得到的部分更多,因为文件的最后一部分也包含“ - ”。

An easy way to solve it is to join the remaining parts like this: 解决它的一个简单方法是加入其余部分,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM