سؤال

أنا ألعب مع مكتبة سلاسل دفعة وقد صادفت للتو البساطة الرائعة لطريقة الانقسام.

  string delimiters = ",";
  string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\"";
  // If we didn't care about delimiter characters within a quoted section we could us
  vector<string> tokens;  
  boost::split(tokens, str, boost::is_any_of(delimiters));
  // gives the wrong result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters", " inside a quote\""}

التي ستكون لطيفة وموجزة ... ومع ذلك لا يبدو أنها تعمل مع اقتباسات وبدلا من ذلك يجب علي فعل شيء مثل ما يلي

string delimiters = ",";
string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\"";
vector<string> tokens; 
escaped_list_separator<char> separator("\\",delimiters, "\"");
typedef tokenizer<escaped_list_separator<char> > Tokeniser;
Tokeniser t(str, separator);
for (Tokeniser::iterator it = t.begin(); it != t.end(); ++it)
    tokens.push_back(*it);
// gives the correct result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters, inside a quote\""}

سؤالي هل يمكن تقسيم أو خوارزمية قياسية أخرى يتم استخدامها عند نقلتها المحددين؟ بفضل purpledog ولكن لدي بالفعل طريقة غير متهمية لتحقيق النتيجة المرجوة، أعتقد أنها مرهقة للغاية وما لم أستطع استبدالها بحل أكثر أبسط أناقة لن أستخدمه بشكل عام دون التفاف أولا طريقة أخرى.

تحرير: التعليمات البرمجية المحدثة لإظهار النتائج وتوضيح السؤال.

هل كانت مفيدة؟

المحلول

لا يبدو أن هناك أي طريقة بسيطة للقيام بذلك باستخدام طريقة Boost :: Split. أقصر قطعة من التعليمات البرمجية يمكنني أن أجدها للقيام بذلك

vector<string> tokens; 
tokenizer<escaped_list_separator<char> > t(str, escaped_list_separator<char>("\\", ",", "\""));
BOOST_FOREACH(string s, escTokeniser)
    tokens.push_back(s);  

وهو ما يزيد فقط عن السفلية أكثر من المقتطف الأصلي

vector<string> tokens;  
boost::split(tokens, str, boost::is_any_of(","));

نصائح أخرى

سيحقق ذلك نفس النتيجة مثل إجابة جيمي كوك دون حلقة صريحة.

tokenizer<escaped_list_separator<char> >tok(str);
vector<string> tokens( tok.begin(), tok.end() );

المعلمة الثانية من منشئ Tokenizer escaped_list_separator<char>("\\", ",", "\"") لذلك ليس من الضروري. ما لم يكن لديك متطلبات مختلفة للفواصل أو الاقتباس.

لا أعرف عن مكتبة Boost :: سلسلة String ولكن باستخدام Boost Regex_token_iterater، ستتمكن من التعبير عن المحددين من حيث التعبير العادي. نعم، يمكنك استخدام المحددات المعروضة والأشياء الأكثر تعقيدا أيضا.

لاحظ أن هذا يستخدم مع Regex_split الذي تم إهماله الآن.

إليك مثال مأخوذ من Doc Bost:

#include <iostream>
#include <boost/regex.hpp>

using namespace std;

int main(int argc)
{
   string s;
   do{
      if(argc == 1)
      {
         cout << "Enter text to split (or \"quit\" to exit): ";
         getline(cin, s);
         if(s == "quit") break;
      }
      else
         s = "This is a string of tokens";

      boost::regex re("\\s+");
      boost::sregex_token_iterator i(s.begin(), s.end(), re, -1);
      boost::sregex_token_iterator j;

      unsigned count = 0;
      while(i != j)
      {
         cout << *i++ << endl;
         count++;
      }
      cout << "There were " << count << " tokens found." << endl;

   }while(argc == 1);
   return 0;
}

إذا بدأ البرنامج به مرحبا بالعالم كما حجة الإخراج هو:

hello
world
There were 2 tokens found.

تغيير دفعة :: Regex Re (" S +")؛ إلى دفعة :: Regex Re (""، ")؛ سوف تقسم المحددات نقلت. بدء البرنامج مع مرحبا بالعالم كما ستؤدي الحجة أيضا إلى:

hello
world
There were 2 tokens found.

لكنني أظن أنك تريد التعامل مع أشياء مثل هذا: "مرحبا بالعالم", ، في هذه الحالة حل واحد هو:

  1. انقسام مع غيبوبة فقط
  2. ثم قم بإزالة "" (ربما باستخدام دفعة / خوارزمية / سلسلة / TRIM.HPP أو مكتبة Regex).

تحرير: إخراج البرنامج المضافة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top