簡體   English   中英

C ++使用開始和結束定界符解析std :: string

[英]C++ parse std::string with begin and end delimiters

我看到只有一個限制器的許多解決方案,但我需要進行一些解析才能解析此$ deli:entry:deli $。 在進入之前和之后都有一個限制器。 有人有主意嗎?

#include <iostream>
#include <string>
#include <vector>

std:string delimiterOpen    = ("$deli:");
std:string delimiterClose   = (":deli$");
std::vector<std:string> vec;

std:string str ("start $deli:foo:deli$ something else $deli:baa:deli$ doesnt matter");

// calculate


//this should be the vector contend:
foo
ba

嘗試這個:

#include <string>
#include <vector>
#include <iostream>

int main()
{
    std::string delimiterOpen    = ("$deli:");
    std::string delimiterClose   = (":deli$");
    std::vector<std::string> vec;

    std::string str ("start $deli:foo:deli$ something else $deli:baa:deli$ doesnt matter");
    int pos1=0,pos2=0;
    while ( (pos1=str.find(delimiterOpen,pos2))!=std::string::npos ){
        if( (pos2=str.find(delimiterClose,pos1))==std::string::npos){
            //error start without end...
            break;
        }else{
            int start=pos1+delimiterOpen.size();
            int length = pos2-start;
            std::string val = str.substr(start,length);
            vec.push_back(val);
        }

    }
    return 0;
}

您可以使用正則表達式。 或者,您可以將簡單的std :: string :: find方法與std :: string :: substr方法一起使用。 像這樣:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    string delimiterOpen    = ("$deli:");
    string delimiterClose   = (":deli$");
    vector<string> vec;

    string str("start $deli:foo:deli$ something else $deli:baa:deli$ doesnt matter");

    size_t posOpen = 0;
    do 
    {
        string lexeme;
        posOpen = str.find(delimiterOpen, posOpen);
        if (posOpen != string::npos)
        {
            posOpen += delimiterOpen.length();

            size_t posClose = str.find(delimiterClose, posOpen);
            if (posClose != string::npos)
            {
                lexeme = str.substr(posOpen, posClose - posOpen);
                vec.push_back(lexeme);
            }
        }
    } while (posOpen != string::npos);

    vector<string>::iterator it;
    for (it = vec.begin(); it != vec.end(); ++it)
    {
        cout << it->c_str() << endl;
    }

    return 0;
}

如果您不想使用正則表達式...

#include <iostream>
#include <string>
#include <vector>

using namespace std;

string delimiterOpen    = ("$deli:");
string delimiterClose   = (":deli$");
int shift = delimiterOpen.size();
vector<string> vec;

string str ("start $deli:foo:deli$ something else $deli:baa:deli$ doesnt matter");

int main() {
vector<string> founds;
int firstPos = str.find(delimiterOpen);
  while (firstPos != string::npos) {
      int lastPos = str.find(delimiterClose, firstPos);
      if (lastPos!=string::npos) {
         founds.push_back(str.substr(firstPos+shift, lastPos-firstPos-shift));
      }
      firstPos = str.find(delimiterOpen, (lastPos==string::npos? firstPos+1:lastPos+1));
  }

  for (vector<string>::iterator it = founds.begin(); it!=founds.end();it++) {
      cout<<(*it)<<endl;
  }
  return 0;
}
void parse(const string& str, 
           const string& delOpen, 
           const string& delClose
           vector<string>& founds /*out*/;)
{
  const string::size_type 
    szOpen (delOpen.sise()), 
    szClose(delClose.size());

  string::size_type p1 (str.find(delOpen));

  while(p1!=string::npos) {
    string::size_type p2(p1==string::npos ? p1 : str.find(delClose, p1+szOpen));
    founds.push_back(str.substr(p1+szOpen, p2));
    p1 = p2==string::npos ? p2 : str.find(dOpen, p2+szClose);
  }

}

Boost.Spirit始終是正確的方法:類型安全,清晰的解析器結構和語法Boost.Spirit您受益。

#include <boost/spirit/home/qi.hpp>
#include <vector>
#include <string>

namespace qi = boost::spirit::qi;
using std::vector;
using namespace qi;

template <typename Iterator = std::string::const_iterator>
struct my_parser : grammar<Iterator, vector<std::string>(), blank_type>
{
  my_parser(const std::string &openingDelim, const std::string &closingDelim) : my_parser::base_type(query)
  {
    open = openingDelim;
    close = closingDelim;
    beforeOpen = *(char_ - open);
    afterOpen = *(char_ - close);
    //when synthesizing the resulting attribute, ignore everything before openingDelim and after closingDelim
    query = (omit[beforeOpen >> open] >> afterOpen >> omit[close]) % beforeOpen;
  }
  rule<Iterator, vector<std::string>(), blank_type> query;
  rule<Iterator, std::string(), blank_type> open, close, beforeOpen, afterOpen;
};


int main()
{
  my_parser<> p("$deli:", ":deli$");
  std::string s("start $deli:foo:deli$ something else $deli:baa:deli$ doesnt matter");
  vector<std::string> result;
  bool b = phrase_parse(s.begin(), s.end(), p, blank, result);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM