Qt 和 std::string 的通用高效修剪算法是什么?
What's the generic & efficient trimming algorithm for Qt & std::string?
要删除前后空格,Qt 提供了 QByteArray::trimmed()
。但是它每次都不必要地复制底层字符串。
是否有任何通用且有效的方法(最好使用模板)为 QByteArray, QString, std:: string
trim 空格?
您可以为它们中的每一个做类似的事情,但它们不使用相同的界面。
void trim(std::string & str)
{
auto first = std::find_if_not(str.begin(), str.end(), [](unsigned char c){ return std::isspace(c); });
auto last = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c){ return std::isspace(c); }).base();
if (first != str.begin())
{
std::move(first, last, str.begin());
}
str.erase(last, str.end());
}
void trim(QString & str)
{
auto first = std::find_if_not(str.begin(), str.end(), [](unsigned char c){ return std::isspace(c); });
str.remove(0, first - str.begin());
auto last = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c){ return std::isspace(c); }).base();
str.resize(last - str.begin());
}
一个简单的方法:
template<typename T>
T& Trim (T& value)
{
auto pos = value.size();
while(pos != 0 and value[--pos] == ' ');
if(++pos < value.size())
value.erase(pos);
if(value.size() > 0)
{
pos = -1;
while(value[++pos] == ' ');
if(pos > 0)
value.erase(0, pos);
}
return value;
}
以上将支持所有具有以下方法的类型,如 std::string
:
size()
operator[] const
erase(pos, n)
不幸的是,Qt 缺少 erase()
(名字是 remove()
)。为了支持 Qt 类型 QString
和 QByteArray
,我们可以有以下包装器:
template<class String>
struct QtWrap
{
String& m_Value;
auto size () const { return m_Value.size(); }
auto erase (int pos) { return m_Value.truncate(pos); }
auto erase (int pos, int length) { return m_Value.remove(pos, length); }
auto& operator[] (const int pos) const { return m_Value.data()[pos]; }
};
用法:
QByteArray s;
QtWrap<QByteArray> qs{s};
Trim(qs); // Tested OK in QtCreator: Modifies the underlying `s`
要删除前后空格,Qt 提供了 QByteArray::trimmed()
。但是它每次都不必要地复制底层字符串。
是否有任何通用且有效的方法(最好使用模板)为 QByteArray, QString, std:: string
trim 空格?
您可以为它们中的每一个做类似的事情,但它们不使用相同的界面。
void trim(std::string & str)
{
auto first = std::find_if_not(str.begin(), str.end(), [](unsigned char c){ return std::isspace(c); });
auto last = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c){ return std::isspace(c); }).base();
if (first != str.begin())
{
std::move(first, last, str.begin());
}
str.erase(last, str.end());
}
void trim(QString & str)
{
auto first = std::find_if_not(str.begin(), str.end(), [](unsigned char c){ return std::isspace(c); });
str.remove(0, first - str.begin());
auto last = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c){ return std::isspace(c); }).base();
str.resize(last - str.begin());
}
一个简单的方法:
template<typename T>
T& Trim (T& value)
{
auto pos = value.size();
while(pos != 0 and value[--pos] == ' ');
if(++pos < value.size())
value.erase(pos);
if(value.size() > 0)
{
pos = -1;
while(value[++pos] == ' ');
if(pos > 0)
value.erase(0, pos);
}
return value;
}
以上将支持所有具有以下方法的类型,如 std::string
:
size()
operator[] const
erase(pos, n)
不幸的是,
Qt 缺少 erase()
(名字是 remove()
)。为了支持 Qt 类型 QString
和 QByteArray
,我们可以有以下包装器:
template<class String>
struct QtWrap
{
String& m_Value;
auto size () const { return m_Value.size(); }
auto erase (int pos) { return m_Value.truncate(pos); }
auto erase (int pos, int length) { return m_Value.remove(pos, length); }
auto& operator[] (const int pos) const { return m_Value.data()[pos]; }
};
用法:
QByteArray s;
QtWrap<QByteArray> qs{s};
Trim(qs); // Tested OK in QtCreator: Modifies the underlying `s`