You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取字符串最后字符?提取版本号时GetBetween方法丢字符问题

问题描述

我有一个包含大量软件包信息的文本文件,部分内容如下:

"Data.Interface.4.87.2"
"GuiTools.4.92.401-alpha01400"
"Drivers.4.87.400-alpha01000"

需要从中提取版本号:4.87.2、4.92.401、4.87.400,但当前使用的GetBetween方法会丢失末尾字符,实际输出与预期不符:

预期输出 : 4.92.401
实际输出 : 4.92.4
预期输出 : 4.87.2
实际输出 : 4.87.
预期输出 : 4.87.400
实际输出 : 4.87.4

以下是用于提取"package "到字符串末尾内容的C#相关方法代码:

private string GetBetween(string strSource, string strStart, string strEnd)
{
    if (strSource.Contains(strStart) && strSource.Contains(strEnd))
    {
        int Start, End;
        Start = strSource.IndexOf(strStart, 0) + strStart.Length;
        End = strSource.IndexOf(strEnd, Start);
        return strSource.Substring(Start, End - Start);
    }

    return "";
}
private string GetPackageVersion(string line)
{
    string packageinfo = GetBetween(line, "package ", line[line.Length-1].ToString());
    string VersionNumber = "";
    for (int i = 0; i < packageinfo.Length; i++)
    {
        if (char.IsDigit(packageinfo[i]) || packageinfo[i] == '.')
        {
            VersionNumber += packageinfo[i];
        }
    }
    VersionNumber = ReverseString(VersionNumber);
    VersionNumber = RemoveDotsFromEndofString(VersionNumber);
    return ReverString(VersionNumber);
}
private string RemoveDotsFromEndofString(string line)
{
    if (line.Contains("alpha"))
    {
        int pos = line.IndexOf("alpha");
        if (pos >= 0)
        {
            line = line.Remove(pos);
        }

        for (int i = line.Length; i >= 0; i--)
        {
            if (line[i - 1] != '.')
            {
                return line;
            }

            line = line.Remove(i - 1, 1);
        }
    }
    for (int i = line.Length; i >= 0; i--)
    {
        if (line[i - 1] != '.')
        {
            return line;
        }

        line = line.Remove(i - 1, 1);
    }

    return "";
}
private string ReverseString(string s)
{
    char[] charArray = s.ToCharArray();
    Array.Reverse(charArray);
    return new string(charArray);
}

问题原因分析

  1. GetBetween方法逻辑错误:调用时传入字符串最后一个字符作为strEnd,如果该字符在字符串中重复出现(比如引号),IndexOf会返回第一个匹配的位置而非最后一个,导致截取内容不完整。
  2. RemoveDotsFromEndofString循环越界:循环条件i >= 0会导致i-1出现负索引触发异常,同时逻辑可能提前终止,截断有效数字。
  3. 拼写错误:GetPackageVersion中最后调用的ReverString是ReverseString的拼写错误,会引发运行时错误。

解决方案

1. 简化版本提取逻辑(推荐)

直接用正则表达式匹配符合x.y.z格式的版本号,避免复杂的字符串操作:

private string GetPackageVersion(string line)
{
    // 去除两端引号
    string cleanedLine = line.Trim('"');
    // 匹配数字.数字.数字的格式
    var versionMatch = System.Text.RegularExpressions.Regex.Match(cleanedLine, @"\d+\.\d+\.\d+");
    return versionMatch.Success ? versionMatch.Value : string.Empty;
}

2. 修复原方法逻辑

修复GetBetween方法(提取到字符串末尾)

如果需要保留从"package "到末尾的提取逻辑,直接截取到字符串末尾即可,无需指定strEnd:

private string GetBetween(string strSource, string strStart)
{
    if (!strSource.Contains(strStart))
        return string.Empty;
        
    int startIndex = strSource.IndexOf(strStart) + strStart.Length;
    return strSource.Substring(startIndex);
}

修复RemoveDotsFromEndofString方法

用更简洁的方式移除末尾的点,避免循环越界:

private string RemoveDotsFromEndofString(string line)
{
    // 移除alpha及后面的内容
    int alphaIndex = line.IndexOf("alpha");
    if (alphaIndex != -1)
        line = line.Substring(0, alphaIndex);
    
    // 移除末尾所有的点
    while (line.EndsWith("."))
        line = line.Remove(line.Length - 1);
    
    return line;
}

修复GetPackageVersion中的拼写错误

将ReverString改为ReverseString:

private string GetPackageVersion(string line)
{
    string packageinfo = GetBetween(line, "package ");
    string VersionNumber = "";
    for (int i = 0; i < packageinfo.Length; i++)
    {
        if (char.IsDigit(packageinfo[i]) || packageinfo[i] == '.')
        {
            VersionNumber += packageinfo[i];
        }
    }
    VersionNumber = ReverseString(VersionNumber);
    VersionNumber = RemoveDotsFromEndofString(VersionNumber);
    return ReverseString(VersionNumber);
}

3. 正确获取字符串最后一个字符的方法

在C#中,有三种可靠方式获取字符串最后一个字符(需确保字符串非空):

  • C# 8.0+ 索引语法:char lastChar = line[^1];
  • 兼容旧版本:char lastChar = line[line.Length - 1];
  • Linq 方法:char lastChar = line.Last();(需引用System.Linq)

内容的提问来源于stack exchange,提问作者Jepsen_s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:54:21