【问题标题】:QString trim non-whitespace characters from line begin or endQString从行开始或结束修剪非空白字符
【发布时间】:2018-04-15 13:31:50
【问题描述】:

有些语言有 ltrim(), rtrim() 函数可以修剪任意字符,但是 Qt 中的 QString 目前似乎没有类似的东西。如何用当前功能实现这样的功能?正则表达式?

注意。如果 Qt 团队可以像其他一些语言一样在 QString() 中添加 add ltrim()、rtrim() 方法,那就太好了:

QString ltrim(QByteArray &chars); // trim left
QString rtrim(QByteArray &chars); // trim right

和重载

trimmed(QByteArray &chars)

修剪任意字符,而不仅仅是空格。应该很方便。

【问题讨论】:

    标签: c++ qt trim qstring


    【解决方案1】:

    如果您认为该功能很重要,则可以在 https://bugreports.qt.io/ 上发布功能请求。如果您查看qstring.cpp,您会发现该函数相当简单,您可以更快地创建自己的自定义函数。

    您可以使用QString::simplified() 修剪空格、\n\r 等;

    qDebug() << QString(" lots\t of\nwhitespace\r\n ").simplified();
    
    Output: lots of whitespace
    

    或者如果您想修剪自定义字母,您可以使用QString::removeQRegExp

    qDebug() << QString("13Hello").remove(QRegExp("^([0-9]{2})")); // trim 2 numbers at begin
    Output: Hello
    
    qDebug() << QString("Hello13").remove(QRegExp("([0-9]{2})$")); // trim 2 numbers at the end
    Output: Hello
    
    qDebug() << QString(",./Hello").remove(QRegExp("^([,|.|/]+)")); // trim matched characters at the begin
    Output: Hello
    
    qDebug() << QString("Hello,./").remove(QRegExp("([,|.|/]+)$")); // trim matched characters at the end
    Output: Hello
    

    【讨论】:

    • 当然trimmed 可以用不同的参数类型重载。这是重载的典型情况,除了 this 类型的重载。
    • 如果不知道要修剪多少个字符怎么办?你能改变你的例子吗?如果想要修剪,例如,所有,/ 等,这是否正确:.remove(QRegExp("^([,/]{*})")
    • 关于bug报告,暂不受理:bugreports.qt.io/browse/QTBUG-67712
    • Aleksey Kontsevich:.remove(QRegExp(^([,|.|\/|]+)); 匹配 |,./+ 表示这里会匹配多次。
    • Aleksey Kontsevich:不要担心被拒绝的错误报告或功能请求。目前有23091个未解决的问题。即使他们接受它,也可能需要数月或数年才能将其整合。最好自己写并提交。
    【解决方案2】:

    QByteArray 不是存储QChars 的方法:QString 是。鉴于此,实施并不复杂。使用ws.containsstd::binary_search之间的切换点应该根据基准来选择。

    trimmedReftrimmedLeftReftrimmedRightRef 是不复制源字符串的优化。当字符串的修剪版本没有超过源字符串时,可以使用它们 - 这样可以避免复制。

    #include <QString>
    #include <algorithm>
    
    namespace detail { struct IsSpace final {
      static QString sorted(QString s) {
        std::sort(s.begin(), s.end());
        return s;
      }
      QString const ws;
      QString::const_iterator begin = ws.cBegin(), end = ws.cEnd();
      bool (IsSpace::*test)(QChar) const = 
        ws.isEmpty()     ? &IsSpace::test1 :
        (ws.size() <= 8) ? &IsSpace::test2 :
                           &IsSpace::test3;
      explicit IsSpace(const QString &whitespace) : ws(sorted(whitespace)) {}
      bool test1(const QChar c) const { return c.isSpace(); }
      bool test2(const QChar c) const { return ws.contains(c); }
      bool test3(const QChar c) const { return std::binary_search(begin, end, c); }
      inline bool operator()(QChar c) const { return (*this.*test)(c); }
    };  }
    
    enum TrimmedOption { TrimmedLeft = 1, TrimmedRight = 2 };
    Q_DECLARE_FLAGS(TrimmedOptions, TrimmedOption)
    Q_DECLARE_OPERATORS_FOR_FLAGS(TrimedOptions)
    QStringRef trimmedRef(const QString &src, const QString &whitespace,
      TrimmedOptions opt = TrimmedLeft | TrimmedRight) {
      detail::IsSpace const isSpace{whitespace};
      int l = 0;
      if (options & TrimmedLeft)
        while (l < src.length() && isSpace(src[l]))
          l++;
      int r = src.length();
      if (options & TrimmedRight)
        while (r > 0 && isSpace(src[r-1]))
          r--;
      return {&src, l, r-l};
    }
    QStringRef trimmedLeftRef(const QString &src, const QString &whitespace = {}) {
      return trimmedRef(src, whitespace, TrimmedLeft);
    }
    QStringRef trimmedRightRef(const QString &src, const QString &whitespace = {}) {
      return trimmed(src, whitespace, TrimmedRight);
    }
    
    QString trimmed(const QString &src, const QString &whitespace,
                    TrimmedOptions opt = TrimmedLeft | TrimmedRight) {
      return trimmedRef(src, whitespace, opt);
    }
    QString trimmedLeft(const QString &src, const QString &whitespace = {}) {
      return trimmedRef(src, whitespace, TrimmedLeft);
    }
    QString trimmedRight(const QString &src, const QString &whitespace = {}) {
      return trimmedRef(src, whitespace, TrimmedRight);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 2022-01-21
      • 2020-04-25
      • 1970-01-01
      相关资源
      最近更新 更多