Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace QRegExp in a string?

I have a string. For example:

QString myString = "Today is Tuesday";

The requirement is: when user types a string, if that string is contained in myString, then that part in the myString should be bold, and case insensitive (Qt::CaseInsensitive), but the format of myString should remain (upper case characters should be upper case and lower case characters should be lower case).

For example:

  • user types: tu -> Today is Tuesday
  • user types: ES -> Today is Tuesday
  • user types: aY -> Today is Tuesday

This is my function:

void myClass::setBoldForMatching( const QString &p_text )
{
  QRegExp regExp( p_text, Qt::CaseInsensitive, QRegExp::RegExp );
  if ( !p_text.isEmpty() )
  {       
    if ( myString.contains( regExp ) )
    {
      myString = myString.replace( p_text, QString( "<b>" + p_text + "</b>" ), Qt::CaseInsensitive );
    }
  }
}

This function is wrong because

user types t -> today is tuesday.

What I need is Today is Tuesday

How should I update my function?

like image 784
songvan Avatar asked Aug 28 '18 09:08

songvan


People also ask

How do you replace a section of a string in regex?

To use RegEx, the first argument of replace will be replaced with regex syntax, for example /regex/ . This syntax serves as a pattern where any parts of the string that match it will be replaced with the new substring. The string 3foobar4 matches the regex /\d. *\d/ , so it is replaced.

Can regex replace characters?

They use a regular expression pattern to define all or part of the text that is to replace matched text in the input string. The replacement pattern can consist of one or more substitutions along with literal characters. Replacement patterns are provided to overloads of the Regex.

Which function is used to replacing pattern in string?

The REGEXREPLACE( ) function uses a regular expression to find matching patterns in data, and replaces any matching values with a new string.


2 Answers

We can use a different QString::replace(), which accepts a QRexExp, to substitute all occurrences. The key to this is that we need a capture group in order to replace the original text in the substitution, using a back-reference (\1):

#include <QRegExp>

QString setBoldForMatching(QString haystack, const QString& needle)
{
    if (needle.isEmpty()) return haystack;
    const QRegExp re{"("+QRegExp::escape(needle)+")", Qt::CaseInsensitive};
    return haystack.replace(re, "<b>\\1</b>");
}

Demo

#include <QDebug>
int main()
{
    qInfo() << setBoldForMatching("THIS DAY (today) is Tuesday.", "Day");
}

THIS DAY (today) is Tuesday.

like image 168
Toby Speight Avatar answered Oct 19 '22 06:10

Toby Speight


Replacing a match with p_text will always change the case to the one of p_text. So you have to do the replacement step by step, like this:

void myClass::setBoldForMatching(const QString &p_text) {
    QRegExp regExp( p_text, Qt::CaseInsensitive, QRegExp::FixedString );

    QString start = "<b>";
    QString stop = "</b>";

    int i=-1;
    while (-1 != (i=myString.indexOf(regExp,i+1))) {
        myString.insert(i, start);
        i += start.size();
        i += p_text.size();
        myString.insert(i, stop);
        i += stop.size();
    }
}

As you can see, with this code, the start and stop tags will be inserted before and after the match, without changing the matched sub-string itself.

Here are some test cases:

  • Today is Tuesday + tu --> Today is Tuesday
  • Today is Tuesday + ES --> Today is Tuesday
  • Today is Tuesday + aY --> Today is Tuesday
  • Today is Tuesday + t --> Today is Tuesday

  • Today is today + To --> Today is today

like image 43
Stanley F. Avatar answered Oct 19 '22 07:10

Stanley F.