简体   繁体   English

在vb.net中提取子字符串

[英]extract substring in vb.net

I have following string, and would need to extract the X and Y values cut to a single digit after the point. 我有以下字符串,并且需要提取切入该点后一位的X和Y值。

A234X78.027Y141.864D1234.2 A234X78.027Y141.864D1234.2

There are a few variables that can change here: 这里有一些变量可以更改:

  • the string can have any length and contain any number of values 字符串可以有任何长度,可以包含任意数量的值
  • I know that X and Y are Always present, but they do not have to be in a specific order in the string 我知道X和Y始终存在,但不必在字符串中按特定顺序排列
  • Each value for X or Y can have any lenght.. for example x can be 1.1 or 1234.1 X或Y的每个值都可以具有任何长度。例如,x可以是1.1或1234.1
  • it is not imperative that X or Y do have a point. X或Y确实必须要有一点。 it can also be a round number, for example X78Y141.34561 (note that X has no point) If there is no point I am ok with the value, but if there is a point then I would need the first digit after the point. 它也可以是一个整数,例如X78Y141.34561(请注意,X没有点)。如果没有点,我可以接受该值,但是如果有一个点,则需要该点之后的第一个数字。 (rounded) (四舍五入)

As a Result of the above string I would need two string variables containing the values 78.0 and 141.9 作为上述字符串的结果,我将需要两个包含值78.0和141.9的字符串变量

EDIT: Updated the last sentence, the variables should contain JUST the value, no X and Y. Sorry for the mistake 编辑:更新了最后一句话,变量应仅包含值,没有X和Y。对不起,错误

Update, code as requested 更新,根据要求编写代码


        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

Have you looked into Regular Expressions? 您是否研究过正则表达式?

    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)

I believe this will do what you are looking for if I understood correctly. 如果我理解正确,我相信这将满足您的需求。

EDIT For Only getting the numbers after X and Y 编辑仅获取X和Y之后的数字

Based off my original code, you could do something like this. 根据我的原始代码,您可以执行以下操作。 This also rounds the numbers to the nearest one decimal place. 这也将数字四舍五入到最接近的小数点后一位。

    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))

Updated code for added code 更新代码以添加代码

    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

Your sample data indicates that fields are separated by letters, and the last letter ends with the string. 您的样本数据表明字段由字母分隔,最后一个字母以字符串结尾。 Knowing that you can parse your desired letters out manually and round to 1 decimal point. 知道您可以手动解析所需的字母并将其舍入到小数点后一位。

This also takes into account when there is no decimal point, but it will display a .0 at the end of the number. 没有小数点时也要考虑到这一点,但数字末尾将显示.0。

EDIT 编辑

Moved common code to a function 将通用代码移至函数

Update 更新资料

Doesn't include the letter as part of the output 不将字母作为输出的一部分

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

Results: 结果:

在此处输入图片说明

Here is a simple LINQ function that should do it for you (no regex, no long code): 这是一个应该为您执行的简单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

Call it like this: 这样称呼它:

Dim s = "A234X78.027Y141.864D1234.2"
Dim x = ExtractX(s, "X"c)
Dim y = ExtractX(s, "Y"c)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM