BOOST :: Split即使使用Token_compress_on将一个空字符串推向向量

boost::split pushes an empty string to the vector even with token_compress_on

本文关键字:一个 向量 字符串 Split Token compress BOOST on      更新时间:2023-10-16

当输入字符串为空白时, boost::split返回一个带有一个空字符串的向量。

是否可以让boost::split返回空矢量?

mcve:

#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
int main() {
    std::vector<std::string> result;
    boost::split(result, "", boost::is_any_of(","), boost::algorithm::token_compress_on);
    std::cout << result.size();
}

输出:

1

所需的输出:

0

压缩压缩相邻的定界符,它不能避免空白令牌。

如果考虑以下内容,则可以看到为什么这始终如一:

活在coliru

#include <boost/algorithm/string.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
int main() {
    for (std::string const& test : {
            "", "token", 
            ",", "token,", ",token", 
            ",,", ",token,", ",,token", "token,,"
        })
    {
        std::vector<std::string> result;
        boost::split(result, test, boost::is_any_of(","), boost::algorithm::token_compress_on);
        std::cout << "n=== TEST: " << std::left << std::setw(8) << test << " === ";
        for (auto& tok : result)
            std::cout << std::quoted(tok, ''') << " ";
    }
}

打印

=== TEST:          === '' 
=== TEST: token    === 'token' 
=== TEST: ,        === '' '' 
=== TEST: token,   === 'token' '' 
=== TEST: ,token   === '' 'token' 
=== TEST: ,,       === '' '' 
=== TEST: ,token,  === '' 'token' '' 
=== TEST: ,,token  === '' 'token' 
=== TEST: token,,  === 'token' '' 

因此,您可以通过从前和结束的修剪定界数来修复它,并检查其余的输入是非空的:

活在coliru

#include <boost/algorithm/string.hpp>
#include <boost/utility/string_view.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
int main() {
    auto const delim = boost::is_any_of(",");
    for (std::string test : {
            "", "token", 
            ",", "token,", ",token", 
            ",,", ",token,", ",,token", "token,,"
        })
    {
        std::cout << "n=== TEST: " << std::left << std::setw(8) << test << " === ";
        std::vector<std::string> result;
        boost::trim_if(test, delim);
        if (!test.empty())
            boost::split(result, test, delim, boost::algorithm::token_compress_on);
        for (auto& tok : result)
            std::cout << std::quoted(tok, ''') << " ";
    }
}

打印:

=== TEST:          === 
=== TEST: token    === 'token' 
=== TEST: ,        === 
=== TEST: token,   === 'token' 
=== TEST: ,token   === 'token' 
=== TEST: ,,       === 
=== TEST: ,token,  === 'token' 
=== TEST: ,,token  === 'token' 
=== TEST: token,,  === 'token' 

奖金:增强精神

使用Spirit X3,在我看来,更灵活,可能更有效:

活在coliru

#include <boost/spirit/home/x3.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
int main() {
    static auto const delim = boost::spirit::x3::char_(",");
    for (std::string test : {
            "", "token", 
            ",", "token,", ",token", 
            ",,", ",token,", ",,token", "token,,"
        })
    {
        std::cout << "n=== TEST: " << std::left << std::setw(8) << test << " === ";
        std::vector<std::string> result;
        parse(test.begin(), test.end(), -(+~delim) % delim, result);
        for (auto& tok : result)
            std::cout << std::quoted(tok, ''') << " ";
    }
}