从字符串中删除空格,不包括 " 和 ' C++ 对之间的部分
Remove whitespace from string excluding parts between pairs of " and ' C++
所以基本上我想做的是从 std::string
对象中删除所有空格,但是不包括语音标记和引号中的部分(所以基本上是字符串),例如:
Hello, World! I am a string
会导致:
Hello,World!Iamastring
但是语音 marks/quote 标记中的内容将被忽略:
"Hello, World!" I am a string
会导致:
"Hello, World!"Iamastring
或者:
Hello,' World! I' am a string
将是:
Hello,' World! I'amastring
是否有一个简单的例程来对字符串执行此操作,可以是内置到标准库中的例程,也可以是如何编写我自己的例程?它不一定是最有效的,因为每次程序 运行s.
时它只会 运行 一次或两次
没有,没有准备好这样的套路
不过您可以自己构建。
您必须遍历字符串并且要使用标志。如果标志为真,则删除空格,如果为假,则忽略它们。当您不在引号中时,该标志为真,否则为假。
这是一个天真的,没有广泛测试的例子:
#include <string>
#include <iostream>
using namespace std;
int main() {
// we will copy the result in new string for simplicity
// of course you can do it inplace. This takes into account only
// double quotes. Easy to extent do single ones though!
string str("\"Hello, World!\" I am a string");
string new_str = "";
// flags for when to delete spaces or not
// 'start' helps you find if you are in an area of double quotes
// If you are, then don't delete the spaces, otherwise, do delete
bool delete_spaces = true, start = false;
for(unsigned int i = 0; i < str.size(); ++i) {
if(str[i] == '\"') {
start ? start = false : start = true;
if(start) {
delete_spaces = false;
}
}
if(!start) {
delete_spaces = true;
}
if(delete_spaces) {
if(str[i] != ' ') {
new_str += str[i];
}
} else {
new_str += str[i];
}
}
cout << "new_str=|" << new_str << "|\n";
return 0;
}
输出:
new_str=|"Hello, World!"Iamastring|
哎呀,我花时间写了这个(简单的)版本:
#include <cctype>
#include <ciso646>
#include <iostream>
#include <string>
template <typename Predicate>
std::string remove_unquoted_chars( const std::string& s, Predicate p )
{
bool skip = false;
char q = '[=10=]';
std::string result;
for (char c : s)
if (skip)
{
result.append( 1, c );
skip = false;
}
else if (q)
{
result.append( 1, c );
skip = (c == '\');
if (c == q) q = '[=10=]';
}
else
{
if (!std::isspace( c ))
result.append( 1, c );
q = p( c ) ? c : '[=10=]';
}
return result;
}
std::string remove_unquoted_whitespace( const std::string& s )
{
return remove_unquoted_chars( s, []( char c ) -> bool { return (c == '"') or (c == '\''); } );
}
int main()
{
std::string s;
std::cout << "s? ";
std::getline( std::cin, s );
std::cout << remove_unquoted_whitespace( s ) << "\n";
}
删除单引号或双引号 C 样式字符串中由给定谓词 除外 内容标识的所有字符,注意尊重转义字符。
我们开始吧。我最终遍历了字符串,如果它找到 "
或 '
,它将翻转忽略标志。如果忽略标志为真且当前字符不是 "
或 '
,迭代器只会递增,直到到达字符串末尾或找到另一个 "
/'
。如果忽略标志为 false,如果当前字符为白色space(space、换行符或制表符),它将删除当前字符。
编辑:此代码现在支持忽略转义字符(\"
、\'
)并确保以 "
开头的字符串以 "
结尾,并且以 '
开头的字符串以 '
结尾,忽略中间的任何其他内容。
#include <iostream>
#include <string>
int main() {
std::string str("I am some code, with \"A string here\", but not here\\". 'This sentence \" should not end yet', now it should. There is also 'a string here' too.\n");
std::string::iterator endVal = str.end(); // a kind of NULL pointer
std::string::iterator type = endVal; // either " or '
bool ignore = false; // whether to ignore the current character or not
for (std::string::iterator it=str.begin(); it!=str.end();)
{
// ignore escaped characters
if ((*it) == '\')
{
it += 2;
}
else
{
if ((*it) == '"' || (*it) == '\'')
{
if (ignore) // within a string
{
if (type != endVal && (*it) == (*type))
{
// end of the string
ignore = false;
type = endVal;
}
}
else // outside of a string, so one must be starting.
{
type = it;
ignore = true;
}
it++;
//ignore ? ignore = false : ignore = true;
//type = it;
}
else
{
if (!ignore)
{
if ((*it) == ' ' || (*it) == '\n' || (*it) == '\t')
{
it = str.erase(it);
}
else
{
it++;
}
}
else
{
it++;
}
}
}
}
std::cout << "string now is: " << str << std::endl;
return 0;
}
你可以像这样使用 erase-remove 习语
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
std::string str("\"Hello, World!\" I am a string");
std::size_t x = str.find_last_of("\"");
std::string split1 = str.substr(0, ++x);
std::string split2 = str.substr(x, str.size());
split1.erase(std::remove(split1.begin(), split1.end(), '\'), split1.end());
split2.erase(std::remove(split2.begin(), split2.end(), ' '), split2.end());
std::cout << split1 + split2;
}
所以基本上我想做的是从 std::string
对象中删除所有空格,但是不包括语音标记和引号中的部分(所以基本上是字符串),例如:
Hello, World! I am a string
会导致:
Hello,World!Iamastring
但是语音 marks/quote 标记中的内容将被忽略:
"Hello, World!" I am a string
会导致:
"Hello, World!"Iamastring
或者:
Hello,' World! I' am a string
将是:
Hello,' World! I'amastring
是否有一个简单的例程来对字符串执行此操作,可以是内置到标准库中的例程,也可以是如何编写我自己的例程?它不一定是最有效的,因为每次程序 运行s.
时它只会 运行 一次或两次没有,没有准备好这样的套路
不过您可以自己构建。
您必须遍历字符串并且要使用标志。如果标志为真,则删除空格,如果为假,则忽略它们。当您不在引号中时,该标志为真,否则为假。
这是一个天真的,没有广泛测试的例子:
#include <string>
#include <iostream>
using namespace std;
int main() {
// we will copy the result in new string for simplicity
// of course you can do it inplace. This takes into account only
// double quotes. Easy to extent do single ones though!
string str("\"Hello, World!\" I am a string");
string new_str = "";
// flags for when to delete spaces or not
// 'start' helps you find if you are in an area of double quotes
// If you are, then don't delete the spaces, otherwise, do delete
bool delete_spaces = true, start = false;
for(unsigned int i = 0; i < str.size(); ++i) {
if(str[i] == '\"') {
start ? start = false : start = true;
if(start) {
delete_spaces = false;
}
}
if(!start) {
delete_spaces = true;
}
if(delete_spaces) {
if(str[i] != ' ') {
new_str += str[i];
}
} else {
new_str += str[i];
}
}
cout << "new_str=|" << new_str << "|\n";
return 0;
}
输出:
new_str=|"Hello, World!"Iamastring|
哎呀,我花时间写了这个(简单的)版本:
#include <cctype>
#include <ciso646>
#include <iostream>
#include <string>
template <typename Predicate>
std::string remove_unquoted_chars( const std::string& s, Predicate p )
{
bool skip = false;
char q = '[=10=]';
std::string result;
for (char c : s)
if (skip)
{
result.append( 1, c );
skip = false;
}
else if (q)
{
result.append( 1, c );
skip = (c == '\');
if (c == q) q = '[=10=]';
}
else
{
if (!std::isspace( c ))
result.append( 1, c );
q = p( c ) ? c : '[=10=]';
}
return result;
}
std::string remove_unquoted_whitespace( const std::string& s )
{
return remove_unquoted_chars( s, []( char c ) -> bool { return (c == '"') or (c == '\''); } );
}
int main()
{
std::string s;
std::cout << "s? ";
std::getline( std::cin, s );
std::cout << remove_unquoted_whitespace( s ) << "\n";
}
删除单引号或双引号 C 样式字符串中由给定谓词 除外 内容标识的所有字符,注意尊重转义字符。
我们开始吧。我最终遍历了字符串,如果它找到 "
或 '
,它将翻转忽略标志。如果忽略标志为真且当前字符不是 "
或 '
,迭代器只会递增,直到到达字符串末尾或找到另一个 "
/'
。如果忽略标志为 false,如果当前字符为白色space(space、换行符或制表符),它将删除当前字符。
编辑:此代码现在支持忽略转义字符(\"
、\'
)并确保以 "
开头的字符串以 "
结尾,并且以 '
开头的字符串以 '
结尾,忽略中间的任何其他内容。
#include <iostream>
#include <string>
int main() {
std::string str("I am some code, with \"A string here\", but not here\\". 'This sentence \" should not end yet', now it should. There is also 'a string here' too.\n");
std::string::iterator endVal = str.end(); // a kind of NULL pointer
std::string::iterator type = endVal; // either " or '
bool ignore = false; // whether to ignore the current character or not
for (std::string::iterator it=str.begin(); it!=str.end();)
{
// ignore escaped characters
if ((*it) == '\')
{
it += 2;
}
else
{
if ((*it) == '"' || (*it) == '\'')
{
if (ignore) // within a string
{
if (type != endVal && (*it) == (*type))
{
// end of the string
ignore = false;
type = endVal;
}
}
else // outside of a string, so one must be starting.
{
type = it;
ignore = true;
}
it++;
//ignore ? ignore = false : ignore = true;
//type = it;
}
else
{
if (!ignore)
{
if ((*it) == ' ' || (*it) == '\n' || (*it) == '\t')
{
it = str.erase(it);
}
else
{
it++;
}
}
else
{
it++;
}
}
}
}
std::cout << "string now is: " << str << std::endl;
return 0;
}
你可以像这样使用 erase-remove 习语
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
std::string str("\"Hello, World!\" I am a string");
std::size_t x = str.find_last_of("\"");
std::string split1 = str.substr(0, ++x);
std::string split2 = str.substr(x, str.size());
split1.erase(std::remove(split1.begin(), split1.end(), '\'), split1.end());
split2.erase(std::remove(split2.begin(), split2.end(), ' '), split2.end());
std::cout << split1 + split2;
}