QString从行开头或结尾修剪非空白字符

时间:2018-04-15 13:31:51

标签: c++ qt trim qstring

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

  

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

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

并重载

trimmed(QByteArray &chars)

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

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

QByteArray无法存储QCharQString是。鉴于此,实施并不复杂。应根据基准选择使用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);
}