在括号内解析字符串

时间:2017-03-17 09:54:54

标签: c++ string

我有一个像这样的字符串:

Room -> Subdiv("X", 0.5, 0.5) { sleep | work } : 0.5

我需要以某种方式提取{}之间的2个字符串,即sleepwork。格式是严格的,括号之间只能有2个单词,但单词可以改变。括号前后的文本也可以更改。我最初的做法是:

string split = line.substr(line.find("Subdiv(") + _count_of_fchars);
split = split.substr(4, axis.find(") { "));
split = split.erase(split.length() - _count_of_chars);

但是,我确实意识到,如果括号内的字符串被更改为长度不同的任何字符串,则无法正常工作。

如何做到这一点?谢谢!

3 个答案:

答案 0 :(得分:2)

类似的东西:

unsigned open = str.find("{ ") + 2;
unsigned separator = str.find(" | ");
unsigned close = str.find(" }") - 2;
string strNew1 = str.substr (open, separator - open);
string strNew2 = str.substr (separator + 3, close - separator);

答案 1 :(得分:1)

不对任何数字进行硬编码:

  • 从字符串末尾查找A作为第一个"{"的索引,向后搜索。
  • B的位置查找"|"作为第一个"{"的索引,向前搜索。
  • C的位置查找"}"作为第一个"|"的索引,向前搜索。

BA之间的子字符串为您提供第一个字符串。虽然CB之间的子字符串为您提供了第一个字符串。您可以在子字符串搜索中包含空格,或稍后将其删除。

std::pair<std::string, std::string> SplitMyCustomString(const std::string& str){
    auto first = str.find_last_of('{');
    if(first == std::string::npos) return {};

    auto mid = str.find_first_of('|', first);
    if(mid == std::string::npos) return {};

    auto last = str.find_first_of('}', mid);
    if(last == std::string::npos) return {};

    return { str.substr(first+1, mid-first-1), str.substr(mid+1, last-mid-1) };
}

修剪空格:

std::string Trim(const std::string& str){
    auto first = str.find_first_not_of(' ');
    if(first == std::string::npos) first = 0;

    auto last = str.find_last_not_of(' ');
    if(last == std::string::npos) last = str.size();

    return str.substr(first, last-first+1);
}

Demo

答案 2 :(得分:1)

即使您说要查找的单词数量是固定的,我使用正则表达式做了一个更灵活的示例。但是,使用Мотяs的答案你仍然可以达到相同的效果。

std::string s = ("Room -> Subdiv(\"X\", 0.5, 0.5) { sleep | work } : 0.5")
std::regex rgx("\\{((?:\\s*\\w*\\s*\\|?)+)\\}");
std::smatch match;

if (std::regex_search(s, match, rgx) && match.size() == 2) {
    // match[1] now contains "sleep | work"
    std::istringstream iss(match[1]);
    std::string token;
    while (std::getline(iss, token, '|')) {
        std::cout << trim(token) << std::endl;  
    }
}

trim删除了前导和尾随空格,输入字符串可以很容易地展开,如下所示:"...{ sleep | work | eat }..."

Here是完整的代码。