Capturing partial coordinates from text file...

I want to read a gcode-file into matlab.. The format looks something like below...
;LAYER:0
M107
G0 F9000 X89.19 Y90.68 Z0.30
;TYPE:SKIRT
G1 F1200 X89.40 Y91.83 E0.05822
G1 X89.67 Y92.97 E0.11703
G1 X90.01 Y94.10 E0.17553
I want to read the G0 and G1 commands, describing positions.. The input not complete and may not hold all coordinates in all lines.. The output I'm looking for is a array (or a table) with the X, Y and Z movements, with a NaN or zero when values are missing.. So something like this:
89.19 90.68 0.30
89.40 91.83 NaN
89.67 92.97 NaN
90.01 94.10 NaN
I've been trying to use regexp, but can't really wrap my head around it..
I've already made a loop based reader, that splits the strings and examines if with IF-statements, but this is timeconsuming, as these files may hold hundred of thousands of commands....

 채택된 답변

Guillaume
Guillaume 2017년 9월 13일

1 개 추천

regular expressions may not be the right tool for this job, particularly, if the order is not guaranteed to be XYZ. If it is guaranteed, then it's possible (you can even do it on the whole file content at once). Unfortunately, Matlab's regular expression engine does not support captures within groups so it requires some post-processing:
filecontent = fileread(fullfile(path, filename));
coordinates = regexp(filecontent, '^G[01][^X\n\r]*(X\d+\.\d+)?[^Y\n\r]*(Y\d+\.\d+)?[^Z\n\r]*(Z\d+\.\d+)?.*$', 'tokens', 'dotexceptnewline', 'lineanchors');
coordinates = vertcat(coordinates{:});
coordinates = str2double(cellfun(@(x) x(2:end), coordinates, 'UniformOutput', false))
The cellfun above is to remove the X/Y/Z prefix that matlab regular expression engine can't remove due to its limitation.
Two assumptions are made in the regular expression:
  • X, if present, is always before Y, if present, which is always before Z, if present. That restriction can't easily be removed.
  • coordinates are of the form digits.digits. That can be changed if they can be just digits (or .digits) at the expense of a more complicated regular expression.
Explanation of the regular expression
^ match beginning of line (because of the lineanchor option)
G match G
[01] match 0 or 1
[^X\n\r]* match anything that is not X or the next line, as many times as necessary
(...)? start the first capture that may not be present, the content of the capture is
\d+\.\d+ match 1 or more digits, a dot, 1 or more digits
repeat the three lines above for Y and Z
.* match anything but new lines (because of the dotexceptnewline option) for the rest of the line
$ match the end of the line (because of the lineanchor option)
Matlab is the only regular expression engine I know (among .Net, C++, python, ruby, java, php) where dot also match a new line. Hence the need for the dotexceptnewline option.

댓글 수: 3

Thank you for this...
However, while the order is always X Y Z, there may also be cases where there's no X or Y, as in the first line below... I can see that my sample-text was unfortunately a bit to short to show this...
G1 Z15.0 F9000 ;move the platform down 15mm
G92 E0 ;zero the extruded length
G1 F200 E3 ;extrude 3mm of feed stock
G92 E0 ;zero the extruded length again
G1 F9000
;Put printing message on LCD screen
M117 Printing...
;Layer count: 336
;LAYER:0
M107
G0 F9000 X89.19 Y90.68 Z0.30
;TYPE:SKIRT
G1 F1200 X89.40 Y91.83 E0.05822
G1 X89.67 Y92.97 E0.11703
G1 X90.01 Y94.10 E0.17553
Yes, I should have thought of that. Easily fixed:
coordinates = regexp(filecontent, '^G[01][^XYZ\n\r]*(X\d+\.\d+)?[^XYZ\n\r]*(Y\d+\.\d+)?[^XYZ\n\r]*(Z\d+\.\d+)?.*$', 'tokens', 'dotexceptnewline', 'lineanchors');
Rest as is.
This works like a charm and cuts down my import-time from ~45 to ~20sec...
Thanks for the help! :)

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Data Import and Export에 대해 자세히 알아보기

태그

질문:

2017년 9월 13일

댓글:

2017년 9월 14일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by