65.9K
CodeProject is changing. Read more.
Home

Reasons to abandon (and replace) QRegExp in your Qt project

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.63/5 (7 votes)

Feb 18, 2014

CPOL

3 min read

viewsIcon

36746

A quick overview why you should abandon Qt's QRegExp class and move on to use QRegularExpression

Introduction

The QRegExp class was introduced a long time ago as a part of the Qt framework. Whilst working with it I discovered a major flaw, rendering it practically unusable for my purposes and another example of the fact that not even powerful frameworks are completely flaw-free. The following little example shall give you an idea why sticking with QRegExp is not a great idea, and moving on to QRegularExpression will make your life easier.

Background

The basic idea behind what I intended to do was to simply validate a QString. The validation criteria was pretty basic: It shall only contain ASCII character which are printable (e.g. ASCII codes 32 - 126), have a minimum length of 1 character and a maximum length of 48 characters. Creating the Regular expression to achieve this was pretty easy,

 (^[\40-\176]{1,47}$) 

does the deed.

Code - A failed attempt with QRegExp

Since I never worked with Regular Expressions in Qt before I decided to Google for Qt Regex. Naturally this search spilled out the QRegExp class at first, with no other results. So I implemented the validation like that:

void parse(QString value)
{
   QRegExp regex("(^[\\40-\\176]{1,47}$)");//Printable ASCII characters only
   if(regex.exactMatch(value))
   {
      //If regex does match - Doesn't work!
   }
}  

The problem with this solution was that even for the simple string "Test" QRegExp never produced an exact match. I was pulling my hair in front of my computer, Expresso and even the .Net equivalent (which I implemented just to test whether Expresso or QRegExp were wrong) were working as expected. After a lot of googling around I found this page, stating a lot of existing bugs which exist within QRegExp (the old Regular Expression engine used by Qt), and some of them seemingly close tangled up with the problem I was dealing with. The following blog entry was in my Google results, sadly I found it after my problem was already solved:

QRegExp has always been known for not being exactly “optimal”: it has an awkward API, it’s slow, buggy, unmaintained , it supports a very limited subset of Perl regexp features, and so on.

The source of my problem (being QRegExp) was found - Now, what was the solution for my problem? Read ahead to find out.

Code - A successful attempt with QRegularExpression

After asking a question about my problem at the Qt Forum I got a very convincing answer by SGaist:
He recommended me to move away from QRegExp to QRegularExpression, and I did:

void parse(QString value)
{   
   QRegularExpression regex("(^[\\40-\\176]{1,47}$)");//Printable ASCII characters only
   if(regex.match(value).hasMatch())
   {
      //If Regex does match - Works!
   }
} 

My hope that this little change would take away all my sorrows and leave me happy with a working RegEx was very dull at the beginning and there was much rejoycing after I found out that it all worked well.
The reason for that? QRegularExpression was introduced with Qt 5.0, and uses a completly new and Perl-compatible RegEx engine, which seemingly took care of an error which consisted within QRegExp.

Why QRegularExpression solved the problem

It was really interesting for me to learn about QRegularExpression, and I recommend who uses Regular Expressions with Qt to move to Qt 5, alone the new RegEx engine and QRegularExpression are amazing things which give a real benefit. The QRegularExpression class implements an almost fully complete Perl-compatible RegEx engine, while the old QRegExp class (and the engine behind) are slow, poorly maintained and supporting only a small subset of the Perl RegEx functionalities. Move ahead to use QRegularExpression, it will enhance your code in any case.