1

I'm trying to remove the middle portion ('G0G90E1' and 'M3S3000') of a string. However, the length from the start to the end will vary, and the number after the 'S' will vary, too (Ex: 'S500', 'S10000', etc.). I'm trying to format this string, which is in ShowContentsOfFile.Text:

'G0G90E1X0Y0M3S3000
'X0Y0
'X1Y1

To this, BUT, only for the copies (which are show in 'E2' and below), which is what the For, Next loop is doing, so, for example, it'll look like this, when I make, say, 5 parts:

'G0G90E1X0Y0M3S3000
'X0Y0
'X1Y1
'E2X0Y0
'X0Y0
'X1Y1
'E3X0Y0
'X0Y0
'X1Y1
'E4X0Y0
'X0Y0
'X1Y1
'E5X0Y0
'X0Y0
'X1Y1

Unfortunately, it also gets rid of the lines below 'E1':

'X0Y0
'X1Y1

Here's my code:

    If NumberOfParts.Text = NumberOfParts.Text Then

        Dim CopySpecificText As String = ShowContentsOfFile.Text

        Dim Start As Integer = CopySpecificText.IndexOf("E1")
        Dim Finish As Integer = CopySpecificText.IndexOf("M")

        Dim DynamicString As String
        Dim x As Integer

        CopySpecificText = CopySpecificText.Replace("G0G90E1", "").Substring(Start, Finish - Start).Trim

        My.Computer.Clipboard.SetText(CopySpecificText)

        For x = 1 To NumberOfParts.Text - 1

            DynamicString = "E" & x + 1
            ShowContentsOfFile.Text += Environment.NewLine & DynamicString & Clipboard.GetText

        Next x

    End If
Bons Silva
  • 11
  • 4
  • You are trying to re-invent the [Mid statement](https://msdn.microsoft.com/en-us/library/xz5s6003.aspx), easier to just use it. – Hans Passant Jan 14 '17 at 22:09

1 Answers1

0

You can split up the first line with a regular expression into the letter+digit(s) parts, e.g. "G0", "G90", "E1", "X0", "Y0", "M3", "S3000".

Then from that you can select the parts you want repeated (e.g. "E1X0Y0") by checking the first character of each part and joining together the chosen parts.

I assumed that the "E" could have a number other than 1 and that you would want to start from that number and add on the number of parts specified in NumberOfParts. I also allowed for there being one-or-more lines after the first line:

Option Infer On
Option Strict On

Imports System.Text.RegularExpressions

Public Class Form1

    Sub MakeNewText()
        Dim copySpecificText() As String = ShowContentsOfFile.Lines
        ' could use Integer.TryParse here to make sure a valid number has been entered:
        Dim nParts = CInt(NumberOfParts.Text)

        ' split the first line into letter-digits pieces and discard the resulting empty parts...
        Dim parts = Regex.Split(copySpecificText(0), "([A-Z][0-9]*)").Where(Function(p) Not String.IsNullOrWhiteSpace(p)).ToList()

        ' to show the parts which were found:
        'ShowContentsOfFile.AppendText(vbCrLf & "Found parts:")
        'For Each p In parts
        '   ShowContentsOfFile.AppendText(vbCrLf & p)
        'Next
        'ShowContentsOfFile.AppendText(vbCrLf & "---")

        ' extract the parts starting with certain letters into a string...
        Dim wantedCodes = "EXY".ToCharArray()
        Dim wantedParts = String.Join("", parts.Where(Function(p) wantedCodes.Contains(p.Chars(0))))

        ' get a string of the X and Y parts...
        Dim xyCodes = "XY".ToCharArray()
        Dim xyString = String.Join("", parts.Where(Function(p) xyCodes.Contains(p.Chars(0))))

        ' get the number from the "E" section:
        Dim eFirstIndex = CInt(parts.First(Function(p) p.StartsWith("E")).Substring(1))
        ' calculate the last index:
        Dim eLastIndex = eFirstIndex + nParts - 1

        For i = eFirstIndex To eLastIndex
            ShowContentsOfFile.AppendText(vbCrLf & "E" & i.ToString() & xyString)
            ShowContentsOfFile.AppendText(vbCrLf & String.Join(vbCrLf, copySpecificText.Skip(1)))

        Next

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MakeNewText()

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' put test data into the text controls:
        NumberOfParts.Text = "5"
        ShowContentsOfFile.Text = "G0G90E1X0Y0M3S3000" & vbCrLf & "X0Y0" & vbCrLf & "X1Y1"

    End Sub

End Class

Result from the above code:

G0G90E1X0Y0M3S3000
X0Y0
X1Y1
E1X0Y0
X0Y0
X1Y1
E2X0Y0
X0Y0
X1Y1
E3X0Y0
X0Y0
X1Y1
E4X0Y0
X0Y0
X1Y1
E5X0Y0
X0Y0
X1Y1

That code should be a bit more modifiable than the code you're trying, although I guess it is G-code and you won't need to modify the program once you have it working.

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • It works! However, I forgot a small detail. Whenever the numbers after the X and/or Y after the E are decimals, negative numbers, or negative decimals, some numbers get skipped! I tried adding [.-] to Regex, and I thought it worked, but it still skips the numbers! :( – Bons Silva Jan 23 '17 at 22:31
  • @BonsSilva In that case, I think you need `([A-Z][0-9.-]*)` as the regex. N.B. [Does a dot have to be escaped in a character class (square brackets) of a regular expression?](http://stackoverflow.com/a/19976308/1115360) et seq. – Andrew Morton Jan 24 '17 at 10:19