Parse large text file
-
Hi,
i am trying to parse a large file that looks like thisN14 X411 Y279.05 N15 G2 X33 Y280.4 I.001 J4.00 N16 G1 X408 Y280.4 N17 G2 X402.3 Y280.09 I-3 J2.65 N18 G1 X402.3 Y280.09 N19 G2 X402.09 Y285.79 I2.7 J2.95 N20 G1 X402.09 Y285.79 ...
I want to extract the X and Y values (rounded) for every line.
I almost got it but cant figure out why i only get X valuesfor exemple
line read : "N619 G1 X48 Y280.4" output : x : "48" but i also need y value
This is my code, can someone tell me please why the while ((posY = rxY.indexIn(line, posY)) != -1) is not entered ?
void ProgramParser::openFile(QString filePath,int ind) { // TODO Implement this /// ... opening the file int minX, minY, maxX, maxY; const QRegularExpression re("X\\d+ Y\\d+"); QRegExp rxX("\\X(\\d+)\\s"); QRegExp rxY("\\Y(\\d+)\\s"); QTextStream in(&file); while(!in.atEnd()) { QString line = in.readLine(); if(line.contains(re)){ int posX = 0; int posY = 0; while ((posX = rxX.indexIn(line, posX)) != -1) { QString lX = rxX.cap(1); qDebug()<<"x : " << lX; posX += rxX.matchedLength(); } while ((posY = rxY.indexIn(line, posY)) != -1) { QString lY = rxY.cap(1); qDebug()<<"y : " << lY; posY += rxY.matchedLength(); } } } file.close(); }
Also, please suggest me a faster solution for this task if you know one.
Thank you very much -
Regular expression don't render very well in this forum, see https://pastebin.com/1rDXQtSL
Source of the regexp for the decimal number: https://www.regular-expressions.info/floatingpoint.html (this is also the answer to @JonB, I don't type, I copy and paste, typing is for smart people)
-
Hi,
The expression you are looking for is
"X(\\d+(?:\\.\\d+)?) Y(\\d+(?:\\.\\d+)?)"
.You should rather do the rounding with the captured data otherwise you will lose precession.
You can use the QRegularExpression tool to test your expressions.
[edit: Fixed RE missing . escaping SGaist]
-
@LeLev take a look again at the expression. I forgot to escape the
.
. Therefore the expression was "wrong" in the sense that it will also find values like X1231a212. -
Hi !
I have lot of troubles trying to use the tool @SGaist
suggested to me. I want to edit my QRegularExpression so it also can catch lines where there is only X or only YN9 G40 X411 Y7.62 // capture N3 G40 Y6000 // << capture this also N1 G0 X411 Y7.52 // capture N3 G40 X-6000 // << capture this also
// ...open file const QRegularExpression regx("X([-+]?\\d*\\.?\\d+)\\s+Y([-+]?\\d*\\.?\\d+)"); QTextStream in(&file); while(!in.atEnd()) { QString line = in.readLine(); const QRegularExpressionMatch reMatch = regx.match(line); bool iok; if(reMatch.hasMatch()){ double lx = reMatch.captured(1).toDouble(); double ly = reMatch.captured(2).toDouble(); qDebug()<<"X : " << lx << " ly" << ly; //please tell me if there is a more efficient way to get maximum/minimum X and maximum/minimum Y in this file, if(lx<minX) minX=lx; else if (lx>maxX) maxX=lx; if(ly<minY) minY=ly; else if (ly>maxY) maxY=ly; } }
My final aim is to get maximum x and y And minimum x and y in the whole file
Thank you -
https://regex101.com/r/n42ANB/1
When and/or if you use it, you must escape it properly for C++.
-
@kshegunov hi
thak you.
i only doubled the " \ "s// (X(-?\d+(?:\.\d+)?))?\s*(Y(-?\d+(?:\.\d+)?))? const QRegularExpression regx("(X(-?\\d+(?:\\.\\d+)?))?\\s*(Y(-?\\d+(?:\\.\\d+)?))?");
I tested your exemple on regex101.com and it is doind what i need. But in My program i get Zeros only
-
Because you are using way more capturing groups than you need and are not handling the case where there's no capture which is allowed since you make the whole thing optional.
What about simplifying things a bit ?
const QRegularExpression rx ("(?:[XY](-?\\d+(?:\\.\\d+)?))"); while (!in.atEnd()) { QString line = in.readLine(); QRegularExpressionMatchIterator iter = re.globalMatch(line); bool ok; while (iter.hasNext()) { QRegularExpressionMatch match = iter.next(); double x_or_y = match.captured(1).toDouble(&ok); if (!ok) { qDebug() << "Failed to convert" << match.captured(1); continue; } if (match.captured(0).startsWith(QLatin1Char('X')) { minX = qmin(minX, x_or_y); maxX = qmax(maxX, x_or_y); } else { minY = qmin(minY, x_or_Y); maxY = qmax(maxY, x_or_y); } }
[edit: fixed rx, escaping was missing SGaist]
-
I'd use:
const QRegularExpression regx("(?:([XY])([-+]?\\d*\\.?\\d+))"); QTextStream in(&file); while(!in.atEnd()) { QString line = in.readLine(); QRegularExpressionMatchIterator iter = re.globalMatch(line); while (iter.hasNext()){ const QRegularExpressionMatch reMatch = iter.next(); if(reMatch.captured(1).compare(QLatin1String("X"),Qt::CaseInsensitive)==0){ // matched X const double lx = reMatch.captured(2).toDouble(); qDebug()<<"X : " << lx; if(lx<minX) minX=lx; else if (lx>maxX) maxX=lx; } else {// matched Y const double ly = reMatch.captured(2).toDouble(); qDebug() << " ly" << ly; if(ly<minY) minY=ly; else if (ly>maxY) maxY=ly; } } }