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. Is there an easy way to count the number of occurrences of wildcards in a QString object?
Forum Updated to NodeBB v4.3 + New Features

Is there an easy way to count the number of occurrences of wildcards in a QString object?

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 3 Posters 2.8k Views 2 Watching
  • 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.
  • JonBJ JonB

    @Robert-Hairgrove
    Personally like I wrote I think I would scan with indexOf(), seems simpler to me than reg ex. May be personal preference!

    I think yours will go wrong on %%%1 etc.? Which is why I think it's trickier with a reg ex than your own code?

    R Offline
    R Offline
    Robert Hairgrove
    wrote on last edited by
    #6

    @JonB No, I tried this on the regex101 site. It was indeed a little tricky to get that part right, but here is the breakdown of the pattern:

    1st capturing group: Looks at the beginning of the string for any character not equal to %, or none, followed by exactly one % followed by 1 or 2 digits;

    2nd (alternate) capture group: Looks for a sequence which MUST begin with a non-% character followed by exactly one % followed by 1 or 2 digits.

    If the string begins with "%1" it will match the first group, but "%%1" does not match anywhere. Anything past the beginning of the string must match the second capture group, and this requires a % preceded by something else and followed by 1 or 2 digits, whereas the non-% character at the beginning of the string is optional (due to the "?" token).

    JonBJ 1 Reply Last reply
    0
    • R Robert Hairgrove

      @JonB No, I tried this on the regex101 site. It was indeed a little tricky to get that part right, but here is the breakdown of the pattern:

      1st capturing group: Looks at the beginning of the string for any character not equal to %, or none, followed by exactly one % followed by 1 or 2 digits;

      2nd (alternate) capture group: Looks for a sequence which MUST begin with a non-% character followed by exactly one % followed by 1 or 2 digits.

      If the string begins with "%1" it will match the first group, but "%%1" does not match anywhere. Anything past the beginning of the string must match the second capture group, and this requires a % preceded by something else and followed by 1 or 2 digits, whereas the non-% character at the beginning of the string is optional (due to the "?" token).

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

      @Robert-Hairgrove
      I don't understand what you are saying. I suggested what will not work:

      %%%1
      

      somewhere/anywhere (beginning/middle/end). That is 3 percent characters. It expands to a literal % followed by your %1 substitution. In my head your reg ex will fail to recognise the %1 because it will see it as a %%1 and so reject the match. Effectively you do not deal with %%s correctly.

      R 1 Reply Last reply
      0
      • JonBJ JonB

        @Robert-Hairgrove
        I don't understand what you are saying. I suggested what will not work:

        %%%1
        

        somewhere/anywhere (beginning/middle/end). That is 3 percent characters. It expands to a literal % followed by your %1 substitution. In my head your reg ex will fail to recognise the %1 because it will see it as a %%1 and so reject the match. Effectively you do not deal with %%s correctly.

        R Offline
        R Offline
        Robert Hairgrove
        wrote on last edited by Robert Hairgrove
        #8

        @JonB Hmmm ... I think you might be right about this. I was probably confusing the SQL LIKE syntax where "%" is also used as a wildcard, and to search for a literal "%" string, one must write it twice, i.e.: WHERE something LIKE '%%1' would match the string '%1' and WHERE something LIKE '%1' would match 'a1', 'b1' etc. So I was deliberately trying NOT to match the wildcard if it had two or more % tokens.

        In that case, the pattern would be much simpler: "%\d{1,2}" which would match anywhere in the string.

        JonBJ 1 Reply Last reply
        0
        • R Robert Hairgrove

          @JonB Hmmm ... I think you might be right about this. I was probably confusing the SQL LIKE syntax where "%" is also used as a wildcard, and to search for a literal "%" string, one must write it twice, i.e.: WHERE something LIKE '%%1' would match the string '%1' and WHERE something LIKE '%1' would match 'a1', 'b1' etc. So I was deliberately trying NOT to match the wildcard if it had two or more % tokens.

          In that case, the pattern would be much simpler: "%\d{1,2}" which would match anywhere in the string.

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

          @Robert-Hairgrove
          Sorry, but again I think you are misunderstanding.

          (Oh, btw, it may not be documented, but I believe Qt does do %% => % for arguments, and I have used that.)

          If you went for %\d{1,2} that would indeed incorrectly cause %%1 to be treated as %1 substitution. You are correct that you do need to deal with %1 versus %%1, as you tried earlier. But I believe you will go wrong on %%%1, you will see it as %%1 and thereby not thing it is a %1 but it is!

          Try abc %1 %%2 %%%3 %%%%4 def with whatever reg ex you choose. I have said I would probably not use reg exs here for this reason, I would just do it via indexOf('%', ...) and deal with the following characters (%, digits, something else) myself. But if you want to use reg ex here you'll have to deal with this issue!

          R 1 Reply Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #10

            I still don't understand the use-case for this though...
            If you want to see what Qt is doing search for findArgEscapes() in qstring.cpp

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            R 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              I still don't understand the use-case for this though...
              If you want to see what Qt is doing search for findArgEscapes() in qstring.cpp

              R Offline
              R Offline
              Robert Hairgrove
              wrote on last edited by
              #11

              @Christian-Ehrlicher The use case would be like this: A function receives a pattern (a string with some wildcards) from some other place and needs to fill in the wildcards within the function, returning the completed string. My function would like to assert that the input has the expected number of wildcards before trying to do replacements.

              1 Reply Last reply
              0
              • JonBJ JonB

                @Robert-Hairgrove
                Sorry, but again I think you are misunderstanding.

                (Oh, btw, it may not be documented, but I believe Qt does do %% => % for arguments, and I have used that.)

                If you went for %\d{1,2} that would indeed incorrectly cause %%1 to be treated as %1 substitution. You are correct that you do need to deal with %1 versus %%1, as you tried earlier. But I believe you will go wrong on %%%1, you will see it as %%1 and thereby not thing it is a %1 but it is!

                Try abc %1 %%2 %%%3 %%%%4 def with whatever reg ex you choose. I have said I would probably not use reg exs here for this reason, I would just do it via indexOf('%', ...) and deal with the following characters (%, digits, something else) myself. But if you want to use reg ex here you'll have to deal with this issue!

                R Offline
                R Offline
                Robert Hairgrove
                wrote on last edited by Robert Hairgrove
                #12

                @JonB I looked at the source code, as @Christian-Ehrlicher suggested, and it appears that QString("%%%1").arg("xyz") would result in the string "%%xyz", although I didn't try it yet.

                JonBJ 1 Reply Last reply
                0
                • R Robert Hairgrove

                  @JonB I looked at the source code, as @Christian-Ehrlicher suggested, and it appears that QString("%%%1").arg("xyz") would result in the string "%%xyz", although I didn't try it yet.

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

                  @Robert-Hairgrove

                  QString("%%%1").arg("xyz") would result in the string "%%xyz"

                  I would expect it to produce %xyz. But in any case the issue is I expect your code to miss the %1 in this case.

                  R 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Robert-Hairgrove

                    QString("%%%1").arg("xyz") would result in the string "%%xyz"

                    I would expect it to produce %xyz. But in any case the issue is I expect your code to miss the %1 in this case.

                    R Offline
                    R Offline
                    Robert Hairgrove
                    wrote on last edited by Robert Hairgrove
                    #14

                    @JonB Finally got around to setting up a little test app (with Qt 5.15.5 on Linux Ubuntu 18.04).
                    This is what it prints:

                    Original:  	Testing %%%1
                    Result:  	Testing %%xyz
                    

                    main.cpp

                    #include <QString>
                    #include <string>
                    #include <iostream>
                    
                    const QString s("Testing %%%1");
                    
                    int main()
                    {
                      const QString rep("xyz");
                      const QString res = s.arg(rep);
                      std::cout
                          << "Original:  \t" << s.toStdString()
                          << "\nResult:  \t" << res.toStdString()
                          << std::endl;
                      return 0;
                    }
                    

                    .pro file:

                    QT -= gui
                    
                    CONFIG += c++11 console
                    CONFIG -= app_bundle
                    
                    # You can make your code fail to compile if it uses deprecated APIs.
                    # In order to do so, uncomment the following line.
                    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
                    
                    SOURCES += \
                            main.cpp
                    
                    # Default rules for deployment.
                    qnx: target.path = /tmp/$${TARGET}/bin
                    else: unix:!android: target.path = /opt/$${TARGET}/bin
                    !isEmpty(target.path): INSTALLS += target
                    
                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      Robert Hairgrove
                      wrote on last edited by
                      #15

                      Changed the regexp now to this:

                      %[1-9][0-9]?
                      

                      Just in case someone writes leading zeroes, i.e. "ABC %01 XYZ" instead of "ABC %1 XYZ". The question mark after the second brackets group is necessary for matching either single digits or two-digit numbers.

                      1 Reply Last reply
                      0

                      • Login

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