如何获取字符串最后字符?提取版本号时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); }
问题原因分析
GetBetween方法逻辑错误:调用时传入字符串最后一个字符作为strEnd,如果该字符在字符串中重复出现(比如引号),IndexOf会返回第一个匹配的位置而非最后一个,导致截取内容不完整。RemoveDotsFromEndofString循环越界:循环条件i >= 0会导致i-1出现负索引触发异常,同时逻辑可能提前终止,截断有效数字。- 拼写错误:
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
相关产品推荐
相关产品推荐

