在 vb.net 中提取子字符串
extract substring in vb.net
我有以下字符串,需要提取 X 和 Y 值,并将其切割成点后的单个数字。
A234X78.027Y141.864D1234.2
这里有几个变量可以改变:
- 字符串可以有任意长度并包含任意数量的值
- 我知道 X 和 Y 始终存在,但它们不必在字符串中按特定顺序排列
- X 或 Y 的每个值可以有任何长度.. 例如 x 可以是 1.1 或 1234.1
- 不一定 X 或 Y 确实有一个点。它也可以是一个整数,例如 X78Y141.34561(注意 X 没有点)如果没有点我可以接受这个值,但如果有点那么我需要点后的第一个数字。 (四舍五入)
作为上述字符串的结果,我需要两个包含值 78.0 和 141.9 的字符串变量
编辑: 更新了最后一句,变量应该只包含值,没有 X 和 Y。抱歉弄错了
更新,代码按要求
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
Dim curline As String = objReader.ReadLine() 'curline = G1X39.594Y234.826F1800.0
If curline.Contains("X") Then
Dim t As String = ExtractPoint(curline, "X"c) 't = "39.594"
Dim d As Double = Math.Round(Convert.ToDouble(t), 1) 'd= 39594.0
destx = d * 10 'destx = 395940
End If
Loop
Function ExtractPoint(dataString As String, character As Char) As String
Dim substring As String = String.Empty
Dim xIndex As Integer = dataString.IndexOf(character) + 1
substring += dataString(xIndex)
xIndex = xIndex + 1
While (xIndex < dataString.Length AndAlso Char.IsLetter(dataString(xIndex)) = False)
substring += dataString(xIndex)
xIndex = xIndex + 1
End While
Return substring
End Function
你研究过正则表达式吗?
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "X\d+([.]\d{1})?")
Dim y As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "Y\d+([.]\d{1})?")
MsgBox(x.ToString & " -- " & y.ToString)
如果我理解正确,我相信这会满足您的需求。
EDIT 仅获取 X 和 Y 之后的数字
根据我的原始代码,您可以这样做。
这也将数字四舍五入到最接近的小数点后一位。
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "X(\d+([.]\d{2})?)")
Dim y As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "Y(\d+([.]\d{2})?)")
MsgBox(Math.Round(CDbl(x.Groups(1).Value), 1) & " -- " & Math.Round(CDbl(y.Groups(1).Value), 1))
更新代码以添加代码
Dim s As String = "A234X78.027Y141.864D1234.2"
Dim dX As Double = Extract(s, "X")
Dim dY As Double = Extract(s, "Y")
MsgBox(dX * 10 & "-" & dY * 10)
Private Function Extract(ByRef a As String, ByRef l As String) As Double
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(a, l & "(\d+([.]\d{2})?)")
Return Math.Round(CDbl(x.Groups(1).Value), 1)
End Function
您的示例数据表明字段之间由字母分隔,最后一个字母以字符串结尾。知道你可以手动解析出你想要的字母并四舍五入到小数点后一位。
这也考虑到了没有小数点的情况,但它会在数字末尾显示一个.0。
编辑
将通用代码移至函数
更新
不将字母作为输出的一部分
Sub Main()
Dim dataString As String = "G1X39.594Y234.826F1800.0"
Dim xString As String = ExtractPoint(dataString, "X"c)
Dim yString As String = ExtractPoint(dataString, "Y"c)
Dim xDouble As Double = Math.Round(Convert.ToDouble(xString), 1)
Dim yDouble As Double = Math.Round(Convert.ToDouble(yString), 1)
Console.WriteLine(xDouble.ToString("F1"))
Console.WriteLine(yDouble.ToString("F1"))
Console.WriteLine((xDouble * 10).ToString("F1"))
Console.WriteLine((yDouble * 10).ToString("F1"))
Console.ReadLine()
End Sub
Function ExtractPoint(dataString As String, character As Char) As String
Dim substring As String = String.Empty
Dim xIndex As Integer = dataString.IndexOf(character) + 1
substring += dataString(xIndex)
xIndex = xIndex + 1
While (xIndex < dataString.Length AndAlso Char.IsLetter(dataString(xIndex)) = False)
substring += dataString(xIndex)
xIndex = xIndex + 1
End While
Return substring
End Function
结果:
这是一个简单的 LINQ 函数,可以为您完成(没有正则表达式,没有长代码):
Private Function ExtractX(s As String, symbol As Char) As String
Dim XPos = s.IndexOf(symbol)
Dim s1 = s.Substring(XPos + 1).TakeWhile(Function(c) Char.IsDigit(c)).ToArray()
If (XPos + 1 + s1.Length < s.Length) AndAlso s.Substring(XPos + 1 + s1.Length)(0) = "."c AndAlso Char.IsDigit(s.Substring(XPos + 1 + s1.Length)(1)) Then
Return String.Join("", s1, s.Substring(XPos + 1 + s1.Length, 2))
Else
Return s1
End If
End Function
这样称呼它:
Dim s = "A234X78.027Y141.864D1234.2"
Dim x = ExtractX(s, "X"c)
Dim y = ExtractX(s, "Y"c)
我有以下字符串,需要提取 X 和 Y 值,并将其切割成点后的单个数字。
A234X78.027Y141.864D1234.2
这里有几个变量可以改变:
- 字符串可以有任意长度并包含任意数量的值
- 我知道 X 和 Y 始终存在,但它们不必在字符串中按特定顺序排列
- X 或 Y 的每个值可以有任何长度.. 例如 x 可以是 1.1 或 1234.1
- 不一定 X 或 Y 确实有一个点。它也可以是一个整数,例如 X78Y141.34561(注意 X 没有点)如果没有点我可以接受这个值,但如果有点那么我需要点后的第一个数字。 (四舍五入)
作为上述字符串的结果,我需要两个包含值 78.0 和 141.9 的字符串变量
编辑: 更新了最后一句,变量应该只包含值,没有 X 和 Y。抱歉弄错了
更新,代码按要求
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
Dim curline As String = objReader.ReadLine() 'curline = G1X39.594Y234.826F1800.0
If curline.Contains("X") Then
Dim t As String = ExtractPoint(curline, "X"c) 't = "39.594"
Dim d As Double = Math.Round(Convert.ToDouble(t), 1) 'd= 39594.0
destx = d * 10 'destx = 395940
End If
Loop
Function ExtractPoint(dataString As String, character As Char) As String
Dim substring As String = String.Empty
Dim xIndex As Integer = dataString.IndexOf(character) + 1
substring += dataString(xIndex)
xIndex = xIndex + 1
While (xIndex < dataString.Length AndAlso Char.IsLetter(dataString(xIndex)) = False)
substring += dataString(xIndex)
xIndex = xIndex + 1
End While
Return substring
End Function
你研究过正则表达式吗?
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "X\d+([.]\d{1})?")
Dim y As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "Y\d+([.]\d{1})?")
MsgBox(x.ToString & " -- " & y.ToString)
如果我理解正确,我相信这会满足您的需求。
EDIT 仅获取 X 和 Y 之后的数字
根据我的原始代码,您可以这样做。 这也将数字四舍五入到最接近的小数点后一位。
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "X(\d+([.]\d{2})?)")
Dim y As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "Y(\d+([.]\d{2})?)")
MsgBox(Math.Round(CDbl(x.Groups(1).Value), 1) & " -- " & Math.Round(CDbl(y.Groups(1).Value), 1))
更新代码以添加代码
Dim s As String = "A234X78.027Y141.864D1234.2"
Dim dX As Double = Extract(s, "X")
Dim dY As Double = Extract(s, "Y")
MsgBox(dX * 10 & "-" & dY * 10)
Private Function Extract(ByRef a As String, ByRef l As String) As Double
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(a, l & "(\d+([.]\d{2})?)")
Return Math.Round(CDbl(x.Groups(1).Value), 1)
End Function
您的示例数据表明字段之间由字母分隔,最后一个字母以字符串结尾。知道你可以手动解析出你想要的字母并四舍五入到小数点后一位。
这也考虑到了没有小数点的情况,但它会在数字末尾显示一个.0。
编辑
将通用代码移至函数
更新
不将字母作为输出的一部分
Sub Main()
Dim dataString As String = "G1X39.594Y234.826F1800.0"
Dim xString As String = ExtractPoint(dataString, "X"c)
Dim yString As String = ExtractPoint(dataString, "Y"c)
Dim xDouble As Double = Math.Round(Convert.ToDouble(xString), 1)
Dim yDouble As Double = Math.Round(Convert.ToDouble(yString), 1)
Console.WriteLine(xDouble.ToString("F1"))
Console.WriteLine(yDouble.ToString("F1"))
Console.WriteLine((xDouble * 10).ToString("F1"))
Console.WriteLine((yDouble * 10).ToString("F1"))
Console.ReadLine()
End Sub
Function ExtractPoint(dataString As String, character As Char) As String
Dim substring As String = String.Empty
Dim xIndex As Integer = dataString.IndexOf(character) + 1
substring += dataString(xIndex)
xIndex = xIndex + 1
While (xIndex < dataString.Length AndAlso Char.IsLetter(dataString(xIndex)) = False)
substring += dataString(xIndex)
xIndex = xIndex + 1
End While
Return substring
End Function
结果:
这是一个简单的 LINQ 函数,可以为您完成(没有正则表达式,没有长代码):
Private Function ExtractX(s As String, symbol As Char) As String
Dim XPos = s.IndexOf(symbol)
Dim s1 = s.Substring(XPos + 1).TakeWhile(Function(c) Char.IsDigit(c)).ToArray()
If (XPos + 1 + s1.Length < s.Length) AndAlso s.Substring(XPos + 1 + s1.Length)(0) = "."c AndAlso Char.IsDigit(s.Substring(XPos + 1 + s1.Length)(1)) Then
Return String.Join("", s1, s.Substring(XPos + 1 + s1.Length, 2))
Else
Return s1
End If
End Function
这样称呼它:
Dim s = "A234X78.027Y141.864D1234.2"
Dim x = ExtractX(s, "X"c)
Dim y = ExtractX(s, "Y"c)