【问题标题】:QString replace only first occurrenceQString 仅替换第一次出现
【发布时间】:2014-01-28 06:39:28
【问题描述】:

有没有简单的方法用 QString 中的其他子字符串替换第一次出现的某些子字符串?它可以在任何位置。

【问题讨论】:

标签: c++ qt qstring qtcore


【解决方案1】:

你可以试试这个:

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

结果字符串将是:

那个字符串

【讨论】:

  • 结果字符串应该是:“this at a string”
  • 如果您尝试匹配 QRegularExpression,这将不起作用,因为它没有“size()”。
  • @Akiva,QRegExpmatchedLength()QRegularExpressionMatchcapturedLength() - 有什么问题?
  • 但是,@TobySpeight 在 newString 中的反向引用(如 \1)不起作用。
  • @Akiva 您可以使用正则表达式的 pos 和 cap 方法来获取文本位置和文本大小。就像我在stackoverflow.com/questions/34612750/… 中解释的那样
【解决方案2】:

这几乎就是 QString::replace(QRegularExpression, ... 的方式。由于文字反斜杠可能是替换模式的一部分,因此需要以不同方式捕获它们。请注意,实际替换发生在正确的位置-left 以保持向左偏移的有效性。可以更紧凑地放置它,但更容易以这种形式进行调试。

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

【讨论】:

    【解决方案3】:
    //------------------------------------------------------------------
    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
    

    【讨论】:

    • 虽然此代码可能有助于解决问题,但提供有关 why 和/或 如何 回答问题的附加上下文将显着改善长期价值。请edit你的答案添加一些解释。
    【解决方案4】:

    您希望进行的操作没有方便的方法。但是,您可以使用以下两种方法来构建您的自定义操作:

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

    返回该字符串中字符串str第一次出现的索引位置,从索引位置开始向前搜索。如果未找到 str,则返回 -1。

    如果 cs 是 Qt::CaseSensitive(默认),则搜索区分大小写;否则搜索不区分大小写。

    QString & QString::replace(int position, int n, const QString & after)

    用后面的字符串替换从索引位置开始的 n 个字符,并返回对该字符串的引用。

    注意:如果指定的位置索引在字符串内,但是 position + n 超出了字符串范围,那么 n 将被调整到在字符串的末尾停止。

    现在,将所有这些付诸实践,您可以编写如下内容:

    main.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;
    }
    

    main.pro

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

    构建并运行

    qmake && make && ./main
    

    输出

    "stuff bar baz" 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-15
      • 2023-01-08
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多