如何在 C++ 中搜索 std::string 中的子字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/346858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you search a std::string for a substring in C++?
提问by Bill the Lizard
I'm trying to parse a simple string in C++. I know the string contains some text with a colon, followed immediately by a space, then a number. I'd like to extract just the number part of the string. I can't just tokenize on the space (using sstream and <<) because the text in front of the colon may or may not have spaces in it.
我正在尝试用 C++ 解析一个简单的字符串。我知道该字符串包含一些带冒号的文本,后跟一个空格,然后是一个数字。我只想提取字符串的数字部分。我不能只对空格进行标记(使用 sstream 和 <<),因为冒号前面的文本可能有也可能没有空格。
Some example strings might be:
一些示例字符串可能是:
Total disk space: 9852465
Free disk space: 6243863
Sectors: 4095
总磁盘空间:9852465
可用磁盘空间:6243863
扇区:4095
I'd like to use the standard library, but if you have another solution you can post that too, since others with the same question might like to see different solutions.
我想使用标准库,但如果您有其他解决方案,您也可以发布该解决方案,因为其他有相同问题的人可能希望看到不同的解决方案。
回答by Brian R. Bondy
std::string strInput = "Total disk space: 9852465";
std::string strNumber = "0";
size_t iIndex = strInput.rfind(": ");
if(iIndex != std::string::npos && strInput.length() >= 2)
{
strNumber = strInput.substr(iIndex + 2, strInput.length() - iIndex - 2)
}
回答by Adam Rosenfield
For completeness, here's a simple solution in C:
为了完整起见,这里有一个简单的 C 解决方案:
int value;
if(sscanf(mystring.c_str(), "%*[^:]:%d", &value) == 1)
// parsing succeeded
else
// parsing failed
Explanation: the %*[^:]
says to read in as many possible characters that aren't colons, and the *
suppresses assignment. Then, the integer is read in, after the colon and any intervening white space.
解释:%*[^:]
说要读入尽可能多的不是冒号的字符,并*
禁止赋值。然后,在冒号和任何中间空格之后读入整数。
回答by Konrad Rudolph
I can't just tokenize on the space (using sstream and <<) because the text in front of the colon may or may not have spaces in it.
我不能只对空格进行标记(使用 sstream 和 <<),因为冒号前面的文本可能有也可能没有空格。
Right, but you can use std::getline
:
是的,但您可以使用std::getline
:
string not_number;
int number;
if (not (getline(cin, not_number, ':') and cin >> number)) {
cerr << "No number found." << endl;
}
回答by Johannes Schaub - litb
Similar to Konrads answer, but using istream::ignore
:
类似于 Konrads 的答案,但使用istream::ignore
:
int number;
std::streamsize max = std::numeric_limits<std::streamsize>::max();
if (!(std::cin.ignore(max, ':') >> number)) {
std::cerr << "No number found." << std::endl;
} else {
std::cout << "Number found: " << number << std::endl;
}
回答by D.Shawley
I'm surprised that no one mentioned regular expressions. They were added as part of TR1 and are included in Boostas well. Here's the solution using regex's
我很惊讶没有人提到正则表达式。它们是作为 TR1 的一部分添加的,并且也包含在Boost中。这是使用正则表达式的解决方案
typedef std::tr1::match_results<std::string::const_iterator> Results;
std::tr1::regex re(":[[:space:]]+([[:digit:]]+)", std::tr1::regex::extended);
std::string str("Sectors: 4095");
Results res;
if (std::tr1::regex_search(str, res, re)) {
std::cout << "Number found: " << res[1] << std::endl;
} else {
std::cerr << "No number found." << std::endl;
}
It looks like a lot more work but you get more out of it IMHO.
看起来需要做更多的工作,但恕我直言,您可以从中获得更多。
回答by orip
const std::string pattern(": ");
std::string s("Sectors: 4095");
size_t num_start = s.find(pattern) + pattern.size();