如何替换字符串中的 QRegExp?

How to replace QRegExp in a string?

我有一个字符串。例如:

QString myString = "Today is Tuesday";

要求是:当用户输入一个字符串时,如果该字符串包含在myString中,那么myString中的那部分应该是粗体,不区分大小写(Qt::CaseInsensitive ), 但 myString 的格式应保留(大写字符应大写,小写字符应小写)。

例如:

这是我的功能:

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 );
    }
  }
}

这个函数是错误的,因为

用户类型 t -> t今天是 t星期二。

我需要的是T一天是T星期

我应该如何更新我的函数?

解决方案

像这样更改您的setBoldForMatching

void myClass::setBoldForMatching(const QString &p_text)
{
    QRegExp regExp(p_text, Qt::CaseInsensitive, QRegExp::RegExp);
    QString str = myString;
    
    if (p_text.isEmpty()) {
        label->setText(myString);
        return;
    }
    
    int count = 0;
    int pos = 0;
    QStringList matches;
    
    while ((pos = regExp.indexIn(str, pos)) != -1) {
        ++count;
        pos += regExp.matchedLength();
        matches.append(regExp.capturedTexts());
    }
    
    foreach (const QString &match, matches) {
        str.replace(match, "<b>" + match + "</b>");
    }
}

我决定保留myString的原始内容,所以结果包含在str中。

例子

我已经为你准备了一个小例子来演示结果。完整代码可在 GitHub.

上找到

结果

p_text 替换匹配项将始终将大小写更改为 p_text 中的一种。所以你必须一步一步地做替换,像这样:

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();
    }
}

如您所见,使用这段代码,开始和结束标记将被插入到匹配之前和之后,而不会改变匹配的子字符串本身。

以下是一些测试用例:

  • 今天是星期二 + tu --> 今天是 Tuesday
  • 今天是星期二 + ES --> 今天是星期二 esday
  • 今天是星期二 + aY --> Today 是星期二ay
  • 今天是星期二 + t --> T今天是 T星期

  • 今天是今天+To --> 天是

我们可以使用接受 QRexExp 的不同 QString::replace() 来替换所有出现的地方。这样做的关键是我们需要一个 捕获组 以便在替换中替换原始文本,使用反向引用 (</code>):</p> <pre><code>#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>"); }

演示

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

THIS DAY (today) is Tuesday.