2

たとえば、文字列が次の場合:

XYZ :: [1] [20 BB EC 45 40 C8 97 20 84 8B 10]

出力は次のようになります。

20 BB EC 45 40 C8 97 20 84 8B 10

int main()
{
    char input = "XYZ ::[1][20 BB EC 45 40 C8 97 20 84 8B 10]";
    char output[500];
    // what to write here so that i can get the desired output as: 
    // output = "20 BB EC 45 40 C8 97 20 84 8B 10"
    return 0;
}
4

8 に答える 8

7

Cでは、スキャンセット変換を使用してこれを行うことができます(ただし、少しREに似ているため、構文が少し奇妙になります)。

sscanf(input, "[%*[^]]][%[^]]]", second_string);

それがどのように機能するのか疑問に思っている場合は、最初[の括弧は文字通り開いた括弧と一致します。%[allowed_chars]次に、またはのように見えるスキャンセットがあります%[^not_allowed_chars]。この場合、最初のまでスキャンしている]ので、%[^]]です。最初の例では、変換仕様のと残りの*間にあります。つまり、そのパターンに一致しようとしますが、無視します。結果を何にも割り当てないでください。その後に、文字通り一致するaが続きます。%sscanf]

次に、基本的に同じことを繰り返しますが、。がない*ため、この変換によって一致する2番目のデータがに割り当てられsecond_stringます。

タイプミスを修正し、最初のコードをスキップするために少し余分なコードを追加するとXYZ ::、動作する(テストされた)コードは次のようになります。

#include <stdio.h>

int main() { 
    char *input = "XYZ ::[1][20 BB EC 45 40 C8 97 20 84 8B 10]";

    char second_string[64];
    sscanf(input, "%*[^[][%*[^]]][%[^]]]", second_string);

    printf("content: %s\n", second_string);
    return 0;
}
于 2012-07-06T06:05:37.933 に答える
6

2番目を見つけて、次[まで抽出(または印刷)を開始し]ます...。

于 2012-07-06T05:39:19.427 に答える
2

に変換する場合は、string::substrを使用できます。std::string

ブラケットの位置がわからない場合はstring::find_last_of、最後のブラケットに使用してstring::find_last_of、開いているブラケットを見つけることができます。

于 2012-07-06T05:41:40.393 に答える
2

たとえば、ファイルは次のようになります。

XYZ ::[1][20 BB EC 45 40 C8 97 20 84 8B 10]
XYZ ::[1][Maybe some other text]
XYZ ::[1][Some numbers maybe: 123 98345 123 9-834 ]
XYZ ::[1][blah-blah-blah]

データを抽出するコードは次のようになります。

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    //opening the file to read from
    std::ifstream file( "in.txt" );
    if( !file.is_open() )
    {
        cout << "Cannot open the file";
        return -1;
    }
    std::string in, out;
    int blockNumber = 1;//Which bracket block we are looking for. We are currently looking for the second one.

    while( getline( file, in ) )
    {
        int n = 0;//Variable for storing index in the string (where our target text starts)
        int i = 0;//Counter for [] blocks we have encountered.
        while( i <= blockNumber )
        {
            //What we are doing here is searching for the position of [ symbol, starting
            //from the n + 1'st symbol of the string.
            n = in.find_first_of('[', n + 1);
            i++;
        }
            //Getting our data and printing it.
        out = in.substr( n + 1, ( in.find_first_of(']', n) - n - 1) );
        std::cout << out << std::endl;
    }
    return 0;
}

これを実行した後の出力は次のようになります。

20 BB EC 45 40 C8 97 20 84 8B 10
Maybe some other text
Some numbers maybe: 123 98345 123 9-834 
blah-blah-blah
于 2012-07-06T06:14:39.347 に答える
2

最も簡単な解決策は、次のようなものです。

std::string
match( std::string const& input )
{
    static boost::regex const matcher( ".*\\[[^]]*\\]\\[(.*)\\]" );
    boost::smatch matched;
    return regex_match( input, matched, matcher )
        ? matched[1]
        : std::string();
}

メタ文字を照合する必要があるため、また私が使用するコンパイラはまだ生の文字列をサポートしていないため、正規表現は少し複雑に見えます。(生の文字列を使用すると、式は次のようになると思います R"^(.*\[[^]]\]\[(.*)\])^"。しかし、それを確認することはできません。)

一致するものがない場合、これは空の文字列を返します。形式について確信がある場合は、例外をスローすることをお勧めします。必要なだけエラーチェックを行うように拡張することもできます。一般に、テキスト入力を検証すればするほど良いのですが、私が完全に記入するのに合法であるという正確な情報を提供していませんでした。 。(たとえば、文字列の例で".*"は、正規表現の先頭にあるを 次のように置き換えることができます"\\u{3}\\s*::":3つの大文字とそれに続く0個以上の空白、次に2つ':'。または最初の[]グループは "\\[\\d\\]"、確実であれば、常に1桁です。

于 2012-07-06T14:41:27.547 に答える
1

Cで文字列ライブラリを使用します。ファイルを1行ずつ読み取るループで使用できる1行を処理するコードスニペットを提供します。注:string.h含める必要があります

    int length = strlen( input );
    char* output = 0;

    // Search
    char* firstBr = strchr( input, '[' );
    if( 0 != firstBr++ ) // check for null pointer
    {
        char* secondBr = strchr(  firstBr, '[' );
        // we don't need '['
        if( 0 != secondBr++ )
        {
            int nOutLen = strlen( secondBr ) - 1;
            if( 0 < nOutLen )
            {
                 output = new char[nOutLen+1];
                 strncpy( output, secondBr, nOutLen );
                 output[ nOutLen ] = '\0';
            }
        }
    }

    if( 0 != output )
    {
        cout << output;
        delete[] output;
        output = 0;
    }
    else
    {
        cout << "Error!";
    }
于 2012-07-06T06:30:22.013 に答える
1

これは、非常に具体的な意味で機能する可能性があります。

std::string str(input);

std::string output(input.find_last_of('['), input.find_last_of(']'));

out = output.c_str();

構文が完全に正しくないため、それを調べる必要があります。おそらく、質問をもう少し適切に定義する必要があります。これは、最後に括弧で囲まれた文字列が必要な場合にのみ機能します。

于 2012-07-06T05:44:24.200 に答える
1

この正規表現を使用して、「<」と「>」の中にあるものを取得できます。

// Regex: "<%999[^>]>" (Max of 999 Bytes)
int n1 = sscanf(source, "<%999[^>]>", dest);
于 2013-09-17T15:48:00.097 に答える