Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Parse large text file
QtWS25 Last Chance

Parse large text file

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 5 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ODБOïO Offline
    ODБOïO Offline
    ODБOï
    wrote on last edited by
    #1

    Hi,
    i am trying to parse a large file that looks like this

    N14 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 values

    for 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

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      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)

      JonBJ 1 Reply Last reply
      4
      • VRoninV VRonin

        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)

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @VRonin How do you type in this answer so fast --- do you have it pre-prepared? :)

        1 Reply Last reply
        1
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by SGaist
          #4

          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]

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          5
          • ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on last edited by
            #5

            You are awesome guys, thank you so much for quick/complete answers

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by SGaist
              #6

              @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.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              ODБOïO 1 Reply Last reply
              2
              • SGaistS 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.

                ODБOïO Offline
                ODБOïO Offline
                ODБOï
                wrote on last edited by ODБOï
                #7

                @SGaist got it, thank you!

                1 Reply Last reply
                0
                • ODБOïO Offline
                  ODБOïO Offline
                  ODБOï
                  wrote on last edited by
                  #8

                  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 Y

                  N9 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

                  kshegunovK 1 Reply Last reply
                  0
                  • ODБOïO ODБOï

                    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 Y

                    N9 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

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #9

                    https://regex101.com/r/n42ANB/1

                    When and/or if you use it, you must escape it properly for C++.

                    Read and abide by the Qt Code of Conduct

                    ODБOïO 1 Reply Last reply
                    2
                    • kshegunovK kshegunov

                      https://regex101.com/r/n42ANB/1

                      When and/or if you use it, you must escape it properly for C++.

                      ODБOïO Offline
                      ODБOïO Offline
                      ODБOï
                      wrote on last edited by
                      #10

                      @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

                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #11
                        This post is deleted!
                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by SGaist
                          #12

                          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]

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          5
                          • VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by VRonin
                            #13

                            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;
                                    }
                                }
                            }
                            
                            1 Reply Last reply
                            4

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved