从文件名中提取版本

时间:2012-12-13 13:33:23

标签: c# arrays string

这是我的示例文件名Text_2.23.txt 我已经分离了扩展,但是我无法将版本删除,因此我可以稍后在代码中使用它进行比较。我需要2.23出来,

编辑:文件名可以有多种形式,但版本总是在文件名的末尾。

string s = f1.Name.ToString(); //for the Filename
int k = s.LastIndexOf('.');
string lhs = k < 0 ? s : s.Substring(0, k), 
    rhs = k < 0 ? "" : s.Substring(k + 1);

char[] array = lhs.ToCharArray();

Array.Reverse(array);           // reverse search from right to left
for (int j = 0; j < array.Length; j++)
{   
    char letter = array[j];     //the letter I get out in the sample case is "3" 
}

3 个答案:

答案 0 :(得分:4)

使用PathVersion类:

string fileName = "Text_2.23.txt";
string fn = Path.GetFileNameWithoutExtension(fileName);
string[] parts = fn.Split('_');

Version v;
if (parts.Length > 1 && Version.TryParse(parts.Last(), out v))
{
    Console.Write("Major:{0}, Minor:{1}", v.Major, v.Minor);
}

Demo

编辑:因为您已经评论过您的文件名几乎是任意的,但版本总是在最后,您只需要string

使用您评论的样本:

string[] fileNames = new[] { "teext_023.ext", "txtxt.x9.08.ext", "text0911.ext" };
string[] versions = fileNames
    .Select(fileName =>
        Path.GetFileNameWithoutExtension(fileName).Split('_')
            .Last()
            .Reverse()
            .TakeWhile(c => c == '.' || Char.IsDigit(c))
            .Reverse()
    ).Select(chars => new string(chars.ToArray())).ToArray();

Demo

答案 1 :(得分:0)

这就是我想要的,一种解决问题的简单方法:

                Array.Reverse(array);  
                Boolean dot = false;
                for (int j = 0; j < array.Length; j++)
                {   
                    char letter = array[j];
                    if (char.IsNumber(letter))
                    {
                        version += letter.ToString();
                    }
                    else if (letter == '.')
                    {
                        if (dot)
                        {
                            break;
                        }
                        dot = true;
                    }
               }
                version = this.Reverse(version);

                if (version.Equals(""))
                {
                    version = "0";
                }

答案 2 :(得分:0)

以下是一些使用正则表达式 (Regex) 从字符串中提取版本号的通用解决方案。

正则表达式(\d+\.\d+\.\d+\.\d+)的解释:

  • ( 开始第一个捕获组
  • \d 匹配一个数字(相当于 [0-9])
  • + 在一次和无限次之间匹配前一个令牌,尽可能多次,根据需要回馈(贪婪)
  • \. 字面上匹配字符 .(区分大小写)
  • ) 关闭第一个捕获组

因此,对于通常使用 X.X.X.X 格式的版本号,只需根据您想要捕获的版本号组件的数量,根据需要多次重复 Regex 模式.

  1. 最简单但最不灵活的解决方案是寻找您需要的确切模式。此方法查找标准的 4 组件版本号。要仅查找由 2 部分组成的版本号,您可以将 Regex 更改为 (\d+\.\d+)
/// <summary>
/// Extracts a version from the given input.
/// </summary>
/// <param name="input">
/// String that may contain a valid 4-component version in the format X.X.X.X.
/// <para>
/// e.g. 1.0.0.0 or 0.0.17.95
/// </para>
/// </param>
/// <returns>Version or null.</returns>
public string ExtractVersionNumber(string input)
{
    var regex = new Regex(@"(\d+\.\d+\.\d+\.\d+)");
    var match = regex.Match(input);
    return match.Success ? match.Value : null;
}
  1. 更灵活的解决方案是指定您是否需要版本号的内部版本号和修订号组件。
/// <summary>
/// Extracts a version number from the given input.
/// </summary>
/// <param name="input">
/// String that may contain a valid version.
/// <para>
/// e.g. 1.0.0.0 or 0.0.17.95
/// </para>
/// </param>
/// <param name="requireBuild">
/// Indicates whether the build component of the version is required.
/// <para>
/// e.g. 1.0.0 or 0.0.17
/// </para>
/// </param>
/// <param name="requireRevision">
/// Indicates whether the revision component of the version is required.
/// <para>
/// e.g. 1.0.0.0 or 0.0.17.95
/// </para>
/// </param>
/// <returns>Version or null.</returns>
public string ExtractVersionNumber(string input, bool requireBuild = true, bool requireRevision = true)
{
    var pattern = @"\d+\.\d+";

    if (requireBuild)
    {
        pattern += @"\.\d+";
    }

    if (requireRevision)
    {
        pattern += @"\.\d+";
    }

    var regex = new Regex($"({pattern})");
    var match = regex.Match(input);
    return match.Success ? match.Value : null;
}
  1. 另一种灵活的方法是指定所需的版本号组件的数量。
/// <summary>
/// Extracts a version from the given input.
/// </summary>
/// <param name="input">
/// String that may contain a valid version number.
/// </param>
/// <param name="componentsRequired">
/// Number of version components required. Defaults to 4.
/// <para>Valid values: 4, 3, 2.</para>
/// <para>4 components example: 1.0.0.0 or 0.1.17.95</para>
/// <para>3 components example: 1.0.0   or 0.1.17</para>
/// <para>2 components example: 1.0     or 0.1</para>
/// </param>
/// <returns>Version or null.</returns>
public string ExtractVersionNumber(string input, int componentsRequired = 4)
{
    string pattern;
    switch (componentsRequired)
    {
        case 4:
            pattern = @"(\d+\.\d+\.\d+\.\d+)";
            break;
        case 3:
            pattern = @"(\d+\.\d+\.\d+)";
            break;
        case 2:
            pattern = @"(\d+\.\d+)";
            break;
        default:
            throw new ArgumentOutOfRangeException(nameof(componentsRequired), "Valid values: 4, 3, 2");
        }

    var regex = new Regex(pattern);
    var match = regex.Match(input);
    return match.Success ? match.Value : null;
}