2017-03-17 29 views
1

之间,我有一个是这样的字符串:解析字符串支架

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

@VittorioRomeo好主意!我更少的C++词汇真的是一个瓶颈!谢谢! –

+1

'{'和'}'之间只能有两个单词吗?或者单词的数量可以变化吗? – muXXmit2X

回答

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

没有硬编码任何数字:

  • 查找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

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是完整的代码。