0

この種の文字列形式があるとします。

"<RGB:255,0,0>this text is colored RED.<RGB:0,255,0> While this text is colored GREEN";

ie 255,0,0内の値を抽出し、<RGB>それを他の変数に入れ、chars from '<'to を削除し'>'ます。

これまでの私のコード:

//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: %c\n", RGBformat[index], RGBformat[i]);
    //but fail in this one
    //this one should erase from '<' until it finds '>'
    RGBformat.erase(index, i);

}

文字列の先頭に を配置する<RGB:?,?,?>と機能しますが、「<」以外の文字の横にあると失敗します。または、これを行うためのより良いアプローチを提案できますか?

4

4 に答える 4

3
  1. 、、およびstd::str::findを検索するために使用します。<RGB:,>
  2. std::str::substr文字列を「切り取る」ために使用します。
  3. 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> .... "あなたの既存のコードに渡された場合、それは壊れてしまいます。なぜなら、退屈してキーを押して停止するか、クラッシュするかのどちらか早い方が来るまで、それは続くからです...

于 2013-06-11T08:27:33.140 に答える
0

ここでは、正規表現を使用できない場合に、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;
}
于 2013-06-11T10:02:47.197 に答える