[英]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.