例如,如果字符串是:
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;
}
答案 0 :(得分:7)
在C中,您可以通过扫描集转换执行此操作(虽然它有点像RE,所以语法有点奇怪):
sscanf(input, "[%*[^]]][%[^]]]", second_string);
如果您想知道它是如何工作的,那么第一个[
会按字面意思与开放式括号匹配。然后你有一个扫描集,看起来像%[allowed_chars]
或%[^not_allowed_chars]
。在这种情况下,您要扫描到第一个]
,因此它是%[^]]
。在第一个中,我们在*
和转换规范的其余部分之间有一个%
,这意味着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;
}
答案 1 :(得分:6)
找到第二个[
并开始提取(或只是打印)直到下一个]
....
答案 2 :(得分:2)
如果您愿意转换为std::string
如果您不知道括号的位置,可以使用string::find_last_of
作为最后一个括号,然后再使用string::find_last_of
查找左括号。
答案 3 :(得分: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
答案 4 :(得分:1)
这可能在非常具体的意义上对你有用:
std::string str(input);
std::string output(input.find_last_of('['), input.find_last_of(']'));
out = output.c_str();
语法不太正确,所以你需要查看它。你可能需要更好地定义你的问题,这只有在你想要最后的字符串时才能使用。
答案 5 :(得分: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!";
}
答案 6 :(得分:1)
最简单的解决方案是:
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();
}
正则表达式看起来有点复杂,因为你需要匹配
元字符,因为我使用的编译器不支持raw
字符串呢。 (使用原始字符串,我认为表达式将是
R"^(.*\[[^]]\]\[(.*)\])^"
。但我无法验证。)
如果没有匹配,则返回空字符串;如果你确定的话
关于格式,您可能更喜欢抛出异常。你也可以
扩展它以根据需要进行尽可能多的错误检查:通常,
您验证文本输入越多越好,但是您没有给出
关于什么对我来说合法的充分信息
完全。 (例如,对于您的示例字符串,您可以替换
正则表达式开头的".*"
"\\u{3}\\s*::"
:三个大写字符后跟零或更多
空格,然后是两个':'
。或者第一个[]组可能是
"\\[\\d\\]"
,如果你确定它总是一位数。
答案 7 :(得分:1)
您可以使用此正则表达式获取“&lt;”内的内容和“&gt;”:
// Regex: "<%999[^>]>" (Max of 999 Bytes)
int n1 = sscanf(source, "<%999[^>]>", dest);