VB.NET中Mid函数无法读取SolAnl1与SolDig字段值求助
问题诊断与解决方案
核心问题
你当前的实现依赖硬编码的字符偏移量和固定读取长度,这种方式完全绑定字符串的固定格式,一旦字段值长度变化、键名后空格数量不同,就会出现读取错误:
- 偏移量计算错误:比如
SolDigPos + 5并没有跳过完整的SolDig:键名(SolDig:共7个字符),导致从键名中间开始读取,出现ldig: ig: :这类错误 - 固定长度读取:比如用
Mid(...,5)读取SolAnl1的值,会把后续的空格或其他字段内容也读进来;读取SolDig时用长度2,会读入多余字符
推荐解决方案:正则表达式提取键值对
正则表达式可以灵活匹配键: 值的模式,完全避免硬编码的问题,适配不同长度的键值内容。
VB.NET代码示例
Imports System.Text.RegularExpressions ' ... 你的网络读取代码保持不变 ... Info = stream_reader.ReadToEnd() sHTML = Info stream_reader.Close() response.Close() ' 正则匹配所有 "键: 值" 格式的内容 Dim pattern As String = "(\w+):\s*(\S+)" Dim matches As MatchCollection = Regex.Matches(sHTML, pattern) ' 遍历匹配结果,提取目标字段 For Each m As Match In matches Dim key As String = m.Groups(1).Value Dim value As String = m.Groups(2).Value Select Case key Case "Temperature" TempCLbl.Text = value TempFLbl.Text = (CDbl(value) * 1.8) + 32 Case "Humidity" HumLbl.Text = value Case "Pressure" Dim presP As Double = CDbl(value) Dim presC As Double = presP / 3386.389 BPresLbl.Text = presC.ToString("F6").Substring(0, 6) Case "SolAnl1" SolAnl1 = value ' PMoistBar1.Value = CInt(value) ' 如果需要转数字 Case "SolDig" SolDig = value txtSerialText.Text = value Case "BattVolt" WSBattLbl.Text = value End Select Next ' 保存变量 TempC = TempCLbl.Text TempF = TempFLbl.Text Hum = HumLbl.Text Pres = BPresLbl.Text WSBattLvl = WSBattLbl.Text txtSerialText2.Text = sHTML
备选方案:拆分字符串遍历
如果不想用正则,也可以按空格拆分字符串,然后遍历找键值:
' ... 读取sHTML之后 ... Dim parts() As String = sHTML.Split({" "}, StringSplitOptions.RemoveEmptyEntries) For i As Integer = 0 To parts.Length - 1 If parts(i).EndsWith(":") Then Dim key As String = parts(i).TrimEnd(":") Dim value As String = parts(i + 1) ' 同上的Select Case逻辑... End If Next
为什么原来的代码会出错?
举个例子,针对你的示例字符串SolAnl1: 1023 SolDig: 1:
SolAnl1Pos是SolAnl1:的起始位置,SolAnl1:共8个字符,SolAnl1Pos +8指向的是冒号后的空格,此时Mid(...,5)会读取1023(包含空格),如果后续字符紧跟,还会读入SolDig的部分SolDigPos是SolDig:的起始位置,SolDig:共7个字符,你用SolDigPos +5指向的是SolDig:中的第6个字符(i),读取长度2就会得到ig,这就是你看到错误内容的原因
内容的提问来源于stack exchange,提问作者justanotherdamnnoob
相关产品推荐
相关产品推荐

