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]or %[^not_allowed_chars]。在这种情况下,您正在扫描到第一个],所以它是%[^]]。在第一个中,我们在转换规范的其余部分*之间有一个,这意味着将尝试匹配该模式,但忽略它——不将结果分配给任何东西。紧随其后的是字面匹配的 a 。%sscanf]

然后我们再次重复基本相同的事情,但没有*,因此与此转换匹配的第二个数据被分配给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

只需找到第二个[并开始提取(或仅打印)直到下一个]....

于 2012-07-06T05:39:19.427 回答
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*::":三个大写字符后跟零个或多个空格,然后是两个':'。或者第一个 [] 组可能是 "\\[\\d\\]",如果您确定它总是一个数字。

于 2012-07-06T14:41:27.547 回答
2

如果您愿意转换为,可以使用string::substrstd::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 回答
1

您可以使用此正则表达式来获取“<”和“>”中的内容:

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

在 C 中使用字符串库。我将给出一个处理单行的代码片段,该代码片段可用于逐行读取文件的循环中。注: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 回答