2017-08-03 70 views
3

我有一个C++函数,其接受字符串在以下格式加倍通过分隔符:允许用户通过其在C++

<WORD>: [VALUE]; <ANOTHER WORD>: [VALUE]; ... 

这是函数:

std::wstring ExtractSubStringFromString(const std::wstring String, const std::wstring SubString) { 

    std::wstring S = std::wstring(String), SS = std::wstring(SubString), NS; 
    size_t ColonCount = NULL, SeparatorCount = NULL; WCHAR Separator = L';'; 

    ColonCount = std::count(S.begin(), S.end(), L':'); 
    SeparatorCount = std::count(S.begin(), S.end(), Separator); 

    if ((SS.find(Separator) != std::wstring::npos) || (SeparatorCount > ColonCount)) 
    { 
     // SEPARATOR NEED TO BE ESCAPED, BUT DON'T KNOW TO DO THIS. 
    } 

    if (S.find(SS) != std::wstring::npos) 
    { 
     NS = S.substr(S.find(SS) + SS.length() + 1); 

     if (NS.find(Separator) != std::wstring::npos) { NS = NS.substr(NULL, NS.find(Separator)); } 
     if (NS[NS.length() - 1] == L']') { NS.pop_back(); } 

     return NS; 
    } 
    return L""; 
} 

以上功能正确地输出MANGO如果我使用它像:

ExtractSubStringFromString(L"[VALUE: MANGO; DATA: NOTHING]", L"VALUE") 

但是,如果我有两个转义分隔符在下面的字符串,我试着像;;翻番,但我仍然得到MANGO代替;MANGO;

ExtractSubStringFromString(L"[VALUE: ;;MANGO;;; DATA: NOTHING]", L"VALUE") 

在这里,价值分配器是冒号和分隔符是分号。我希望允许用户通过将额外的倍数加倍来将冒号和分号传递给我的函数。就像我们在很多脚本语言和编程语言中使用双引号,单引号和许多其他语言一样,也使用许多程序命令的参数。

我以为很难,但甚至想不出一种办法。任何人都可以在这种情况下帮助我吗?

在此先感谢。

+1

*加倍额外的人* - 为什么不遵循这样的事情,并在前面加上事实上的约定“\”如果它被认为是一个文字字符而不是分隔符的话?加倍这样的项目使得这项工作变得更加困难,海事组织 - 当你看到一个“\”时,你知道下一个字符被认为是没有特殊意义的文字字符。 – PaulMcKenzie

+1

我会建议查找json - 为什么要重新发明轮子? – UKMonkey

+0

@AlexG那么如果string包含';;;'? – Blueeyes789

回答

2

您应该在字符串中搜索;;,并用临时填充符charstring替换它,稍后可以引用它并将其替换为该值。

所以基本上:

1)搜索通过串并与替换的;;所有实例\tempFill
- 这将是最好挑字符的组合,将是极不可能在原字符串。
2)解析字符串
3)替换为的\tempFill所有实例;

注:这将是明智的,在您的字符串运行断言,以确保您的\tempFill(或任何你选择填充)不在原始字符串中以防止错误/错误/错误。您可以使用诸如\n之类的字符,并确保原始字符串中有非字符。

声明: 我几乎可以保证有更干净和更有效的方法来做到这一点,但这是最简单的方法。

+0

@SergeBallesta我添加了一个注释来运行断言,但我会添加另一个警告。感谢您的高举。当他们开始谈话时,我删除了我的评论:)。 –

2

首先作为子串不需要被分割我假设它不需要预处理来过滤转义分隔符。

然后在主字符串上,最简单的方法是当您在字符串中搜索它们时,过滤掉转义分隔符。伪代码(假设封闭[]已被删除):

last_index = begin_of_string 
index_of_current_substring = begin_of_string 
loop: search a separator starting at last index - if not found exit loop 
    ok: found one at ix 
    if char at ix+1 is a separator (meaning with have an escaped separator 
     remove character at ix from string by copying all characters after it one step to the left 
     last_index = ix+1 
     continue loop 
    else this is a true separator 
     search a column in [ index_of_current_substring, ix [ 
     if not found: error incorrect string 
     say found at c 
     compare key_string with string[index_of_current_substring, c [ 
     if equal - ok we found the key 
      value is string[ c+2 (skip a space after the colum), ix [ 
      return value - search is finished 
     else - it is not our key, just continue searching 
      index_of_current_substring = ix+1 
      last_index = index_of_current_substring 
      continue loop 

现在应该很容易将其转换成C++