Pergunta

Existe uma maneira simples de substituir apenas a primeira ocorrência de alguma substring por outra substring em QString?Pode estar em qualquer posição.

Foi útil?

Solução

Você poderia tentar isso:

QString str("this is a string"); // The initial string.
QString subStr("is"); // String to replace.
QString newStr("at"); // Replacement string.

str.replace(str.indexOf(subStr), subStr.size(), newStr);

A string resultante será:

isso é uma corda

Outras dicas

Não existe um método de conveniência para a operação que você deseja realizar.No entanto, você pode usar os dois métodos a seguir para criar sua operação personalizada:

int QString::indexOf(const QString & str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const

Retorna a posição do índice da primeira ocorrência da string str nesta string, pesquisando a partir da posição do índice from.Retorna -1 se str não for encontrado.

Se cs for Qt::CaseSensitive (padrão), a pesquisa diferencia maiúsculas de minúsculas;caso contrário, a pesquisa não diferencia maiúsculas de minúsculas.

e

QString e QString::replace(int posição, int n, const QString e depois)

Substitui n caracteres começando na posição do índice pela string posterior e retorna uma referência a esta string.

Observação:Se o índice de posição especificado estiver dentro da string, mas position + n estiver fora do intervalo de strings, então n será ajustado para parar no final da string.

Agora, colocando tudo isso em prática, você poderia escrever algo assim:

principal.cpp

#include <QString>
#include <QDebug>

int main()
{
    QString initialString = QLatin1String("foo bar baz");
    QString fooString = QLatin1String("foo");
    initialString.replace(initialString.indexOf(fooString),
                          fooString.size(), QLatin1String("stuff"));
    qDebug() << initialString;
    return 0;
}

principal.pro

TEMPLATE = app                                         
TARGET = main                                              
QT = core                                              
SOURCES += main.cpp

Construir e executar

qmake && make && ./main

Saída

"stuff bar baz" 

This is pretty much the way QString::replace(QRegularExpression, ... does it. Since it's possible that literal backslashes could be part of replace pattern, those need to be captured differently. Note that actual replacement happens right-to-left to preserve leftward offset validity. It's possible to put this more compactly, but easier to debug in this form.

QRegularExpression regex = QRegularExpression(regex_pattern);

if (regex.isValid() and
    (regex_pattern.length() > 0)) {
    QRegularExpressionMatchIterator regex_iterator =
                                      regex.globalMatch(target_text, Apply_Target_Offset,
                                                        QRegularExpression::PartialPreferCompleteMatch);
    if (regex_iterator.hasNext()) {
        // At least one found
        QRegularExpressionMatch match = regex_iterator.next();
        if (match.hasMatch() and (not match.hasPartialMatch())) {
            // This is the first match, and it's complete
            int match_begin = match.capturedStart();
            int match_end = match.capturedEnd();
            int match_length = match.capturedLength();

            QStringList captured;
            const int capture_groups_count = regex.captureCount() + 1;
            for (int capture_group_idx = 0; capture_group_idx < capture_groups_count; ++capture_group_idx) {
                captured.append(match.captured(capture_group_idx));
            }

            QString replace_pattern = Apply_Replace_Pattern->toPlainText();
            QString replace_text = replace_pattern;
            QList<QRegularExpressionMatch> replace_pattern_match_list;
            QRegularExpression replace_pattern_regex = QRegularExpression("(?:\\\\\\\\)+|(?:\\\\(\\d+))");
            if (replace_pattern_regex.isValid()) {
                QRegularExpressionMatchIterator replace_pattern_regex_iterator =
                                                  replace_pattern_regex.globalMatch(replace_pattern);
                while (replace_pattern_regex_iterator.hasNext()) {
                    QRegularExpressionMatch replace_pattern_match = replace_pattern_regex_iterator.next();
                    bool no_error;
                    replace_pattern_match.captured().right(1).toInt(&no_error);
                    // Only accept backreferences w/ numbers
                    if (no_error) replace_pattern_match_list.append(replace_pattern_match);
                }

                while (replace_pattern_match_list.count() > 0) {
                    QRegularExpressionMatch replace_pattern_match = replace_pattern_match_list.takeLast();
                    int cap_idx = replace_pattern_match.captured(1).toInt();
                    if (cap_idx < captured.count()) {
                        replace_text.replace(replace_pattern_match.capturedStart(),
                                             (replace_pattern_match.capturedEnd() -
                                              replace_pattern_match.capturedStart()),
                                             captured[cap_idx]);
                    }
                }

                // Render '\' characters properly
                replace_text.replace("\\\\", "\\");
            }

            target_text.replace(match_begin, (match_end - match_begin), replace_text);
        }
    }
}
//------------------------------------------------------------------
QString & replace_first(QString &io_haystack, const QString & sub_str, const QString & new_str)
{
  io_haystack.replace(io_haystack.indexOf(sub_str), sub_str.size(), new_str);
  return io_haystack;
} // replace_first
//------------------------------------------------------------------
QString & replace_first(QString &io_haystack, const QRegularExpression & sub_regx, const QString & new_str)
{
  QRegularExpressionMatch match;
  match = sub_regx.match(io_haystack);
  if (match.hasMatch()) {
    QString sub_str = match.captured(0);
    io_haystack.replace(io_haystack.indexOf(sub_str), sub_str.size(), new_str);
  }
  return io_haystack;
} // replace_first
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top