1

I've been banging my head against this for 2 days and still can't crack it.

I have Gcode files with hundreds of lines of XY position data and I'm trying to work out the regex to extract only the float values following the "X" and "Y" characters.

each line of Gcode usually likes this and is fairly simple to work with

G1X445.71Y602.47

but occasionally I have odd lines like these which make it a whole lot more tricky

G1X446.11     // no Y value
G1Y601.91     // no X value
G1X445.73Y602.26S76.5F300    // Y value is followed by S or F values

I'm try to work out the regex to extract only the X and Y values in any of these situations. the values are always positive floats. so magic regex code something like this

var lineData = "G1X445.71Y602.47";
var X = lineData.match(/regex_to_find_X_float/)
var Y = lineData.match(/regex_to_find_Y_float/)

//resulting in: X= 445.71 Y= 602.47 

and for the occasional inconsistent lines

  • G1X446.11 --> X= 446.11 Y=null (adds a null for the missing Y value)
  • G1Y601.91 --> X= null Y= 601.91 (adds a null for the missing X value
  • G1X445.73Y602.26S76.5F300 --> X= 445.73 Y=602.26 (ignores the F and S values)

the closest i've come is X(?:\d+\.\d+|\d+) but it still keeps the X as in "X445.71"

any suggestions very greatly appreciated...

23fps
  • 11
  • 2

2 Answers2

1

If the values are always positive float values, you can use an alternation with 3 capture groups where the Y value is either in group 2 or group 3.

X(\d+\.\d+)(?:Y(\d+\.\d+))?|Y(\d+\.\d+)
  • X(\d+\.\d+) Match X and capture the digit part in group 1
  • (?:Y(\d+\.\d+))? Optionally match Y and capture the digit part in group 2
  • | Or
  • Y(\d+\.\d+) Match Y and the digit part in group 3

Regex demo

Then you can check the capture group values.

const regex = /X(\d+\.\d+)(?:Y(\d+\.\d+))?|Y(\d+\.\d+)/;
[
  "G1X445.71Y602.47",
  "G1X446.11",
  "G1Y601.91",
  "G1X445.73Y602.26S76.5F300"
].forEach(s => {
  const m = s.match(regex);
  if (m) {
    if (m[1]) console.log(`X: ${m[1]}`);
    if (m[2]) console.log(`Y: ${m[2]}`);
    if (m[3]) console.log(`Y: ${m[3]}`);
    console.log("---------------------------");
  }
});
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

I found article related to your work. Check follow URL

https://regexr.com/4222s

I suggest you to try to delete "X" using slice() function after finding "X445.71".

var X = lineData.match(/regex_to_find_X_float/).slice(1)
snowman729
  • 19
  • 3
  • yes, this is effectively what I'm doing at the moment, I was just sure there must be a way to do it inside the regex without the string operation... – 23fps Jun 29 '21 at 01:46
  • I'm sorry to not help you. Sometimes I notice that thinking in different way is helpful. – snowman729 Jun 29 '21 at 18:12