如何提取和删除std::字符串中的字符
How to extract and delete the chars in a std::string
假设我有这样的字符串格式:
"<RGB:255,0,0>this text is colored RED.<RGB:0,255,0> While this text is colored GREEN";
我想提取<RGB>
内部的值,即255,0,0,并将其放在其他变量上,然后从'<'
删除char
到'>'
。
我的代码:
//this function is called after the loop that checks for the existence of '<'
void RGB_ExtractAndDelete(std::string& RGBformat, int index, RGB& rgb)
{
int i = index + 5; //we are now next to character ':'
std::string value;
int toNumber;
while (RGBformat[i] != ',')
{
value += RGBformat[i++];
}
++i;
std::stringstream(value) >> toNumber;
rgb.R = toNumber;
value = "";
while (RGBformat[i] != ',')
{
value += RGBformat[i++];
}
++i;
std::stringstream(value) >> toNumber;
value = "";
rgb.G = toNumber;
while (RGBformat[i] != '>')
{
value += RGBformat[i++];
}
++i;
std::stringstream(value) >> toNumber;
value = "";
rgb.B = toNumber;
//I got the right result here which is
//start: <, end: >
printf("start: %c, end: %cn", RGBformat[index], RGBformat[i]);
//but fail in this one
//this one should erase from '<' until it finds '>'
RGBformat.erase(index, i);
}
如果我把<RGB:?,?,?>
放在字符串的开头,它可以工作,但当它发现它旁边有一个非'<'字符时,它会失败。或者你能建议更好的方法来做到这一点吗?
- 使用
std::str::find
定位<RGB
,:
,,
和>
。 - 使用
std::str::substr
"cut out"字符串。 - 添加
if (!std::strinstream(value)>> toNumber) ...
检查号码是否被实际接受。
像这样:
std::string::size_type index = std::RGBformat.find("<RGB");
if (index == std::string::npos)
{
... no "<RGB" found
}
std::string::size_type endAngle = std::RGBformat::find(">", index);
if (endAngle == std::string::npos)
{
... no ">" found...
}
std::string::size_type comma = std::RGBformat.find(",", index);
if (comma == std::string::npos && comma < endAngle)
{
... no "," found ...
}
std::string value = RGBformat.substr(index, comma-index-1);
std::stringstream(value) >> toNumber;
value = "";
rgb.R = toNumber;
std::string::size_type comma2 = std::RGBformat.find(",", comma+1);
if (comma2 == std::string::npos && comma2 < endAngle)
...
请注意,这可能看起来比您当前的代码更笨拙,但它的优点是更安全。如果有人将"<RGB:55> .... "
传递到你现有的代码中,它就会崩溃,因为它会一直运行,直到你感到无聊并按下一个键来停止它,或者它崩溃,无论哪个先发生……
如果您可以使用Boost或c++ 11,那么这里确实是正则表达式的完美场所。
你可以用"\<RGB:(\d{1,3}),(\d{1,3}),(\d{1,3})\>"
来匹配你的颜色说明符——或者如果你有c++ 11的原始字符串文字,你可以把它写成R"rx(<RGB:(d{1,3}),(d{1,3}),(d{1,3})>)rx"
。
用
解析std::getline
http://en.cppreference.com/w/cpp/string/basic_string/getline 此函数接受分隔符(例如:'<'或'>')作为第三个参数。例如:
基本c++程序,getline()/解析文件
这里有一个修改后的代码,当我不能使用regexp时,我使用它从html中提取文本并从html标记中检索数据。否则,我建议你使用正则表达式,它们更容易设置。
在我的代码中,我以"结束我的标签,颜色为"<RGB:255,0,0> my text"。
希望对你有帮助!
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
typedef struct{
string text;
uint8_t r;
uint8_t g;
uint8_t b;
}TextInfo;
vector<TextInfo> vect;
const vector<TextInfo> & extractInfos(const string & str){
string newStr = str;
vect.clear();
do{
TextInfo info;
int index = newStr.find('>');
if(index != -1 && newStr.find('<') == 0){
// We get "<RGB:r,g,b>"
string color = newStr.substr(0,index+1);
// We extract red color
string red = color.substr(color.find(':') + 1, color.find(',') - color.find(':') - 1);
// We get "g,b>"
color = color.substr(color.find(',') + 1, color.length() - color.find(','));
// We extract green color
string green = color.substr(0,color.find(','));
// We extract "b>"
color = color.substr(color.find(',') + 1, color.length() - color.find('>'));
// We get blue color;
string blue = color.substr(0,color.find('>'));
// string to int into a uint8_t
info.r = atoi(red.c_str());
info.g = atoi(green.c_str());
info.b = atoi(blue.c_str());
// We remove the "<RGB:r,g,b>" part from the string
newStr = newStr.substr(index+1,newStr.length()-index);
index = newStr.find("</>");
// We get the text associated to the color just extracted
info.text = newStr.substr(0,index);
// We remove the "</>" that ends the color
newStr = newStr.substr(index+3,newStr.length()-(index+2));
}else{
// We extract the string to the next '<' or to the end if no other color is set
int i = newStr.find('<');
if(i == -1){
i=newStr.length();
}
info.text = newStr.substr(0,i);
info.r = 0;
info.g = 0;
info.b = 0; // No color then we put default to black
// We get the new part of the string without the one we just exctacted
newStr = newStr.substr(i, newStr.length() - i);
}
// We put the data into a vector
vect.push_back(info);
}while(newStr.length() != 0); // We do it while there is something to extract
return vect;
}
int main(void){
vector<TextInfo> myInfos = extractInfos("<RGB:255,0,0>String to red</><RGB:0,255,0>Green string</>Default color string");
for(vector<TextInfo>::iterator itr = myInfos.begin();itr != myInfos.end();itr++){
cout << (*itr).text << endl;
}
return 0;
}
相关文章:
- 我可以重新分配/覆盖std::字符串吗
- 如何将这个std::字符串转换为std::基本字符串
- std::字符串与 PCWSTR 的对话
- 重载 std::字符串运算符+ 用于打印枚举名称
- 从std::字符串创建OssBitString
- std::字符串擦除以删除最后一个字母
- 如何使用 C++ 中的原语初始化类(如 std::字符串从 const char* 初始化)
- std::字符串串联操作
- 如何有效地将一个大std::字符串的一部分转换为float
- 转义std::字符串中的特殊字符
- 用C++替换std::字符串中的一个子字符串,但不能全部替换
- C++std::字符串流到常量字符*的转换
- 如何将std::字符串转换为不同的字符串类
- 对齐C++字符串类型问题 std::字符串到 TStr
- std::字符串到字符*而不切割字节
- 编写具有非ASCII数据的std ::字符串
- 将 Delphi 的字符串转换为 std::字符串用于C++
- std::字符串添加到字符*
- 字符* 和 std::字符串和常量字符*之间的转换
- 用指针访问std ::字符串中的元素