BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end(), 'o' ) );
}
+BOOST_AUTO_TEST_CASE(testsplitEscapedWithEmpty)
+{
+ string s( "simple:non-escaped:string" );
+ vector<string> v;
+
+ BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
+ BOOST_CHECK_EQUAL(v.size(), 3);
+
+ v.clear();
+ s = "non-escaped:with::spaces:";
+ BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 5);
+ BOOST_CHECK_EQUAL(v.size(), 5);
+
+ v.clear();
+ s = "::";
+ BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
+ BOOST_CHECK_EQUAL(v.size(), 3);
+
+ v.clear();
+ s = ":escaped::with\\:spaces";
+ BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 4);
+ BOOST_CHECK_EQUAL(v.size(), 4);
+}
+
BOOST_AUTO_TEST_CASE(test_escape)
{
string badass = "bad|ass\\|worse";
* "quoted line" -> 1 element same as above
* 'quoted line' -> 1 element same as above
* "escaped quote\'" -> 1 element ( "escaped quote'" )
+ *
+ * \param line_r The string to parse.
+ * \param result_r
+ * \param sepchars_r String of separator characters.
+ * \param withEmpty Whether to include empty fields between separators in the result.
+ *
* \endcode
- */
+ */
template<class _OutputIterator>
unsigned splitEscaped( const C_Str & line_r,
_OutputIterator result_r,
- const C_Str & sepchars_r = " \t" )
+ const C_Str & sepchars_r = " \t",
+ bool withEmpty = false)
{
const char * beg = line_r;
const char * cur = beg;
+ unsigned ret = 0;
+
// skip leading sepchars
while ( *cur && ::strchr( sepchars_r, *cur ) )
+ {
++cur;
- unsigned ret = 0;
+ if (withEmpty)
+ {
+ *result_r = "";
+ ++ret;
+ }
+ }
+
+ // there were only sepchars in the string
+ if (!*cur && withEmpty)
+ {
+ *result_r = "";
+ return ++ret;
+ }
+
+ // after the leading sepchars
for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
{
if ( *cur == '"' || *cur == '\'' )
*result_r = s;
}
// skip sepchars
+ if ( *cur && ::strchr( sepchars_r, *cur ) )
+ ++cur;
while ( *cur && ::strchr( sepchars_r, *cur ) )
+ {
++cur;
+ if (withEmpty)
+ {
+ *result_r = "";
+ ++ret;
+ }
+ }
+ // the last was a separator => one more field
+ if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
+ {
+ *result_r = "";
+ ++ret;
+ }
}
return ret;
}
* ":a:" -> words 3 ||a||
*
* \endcode
- *
+ *
* \code
* std::vector<std::string> words;
* str::split( "some line", std::back_inserter(words) )
}
return ret;
}
+
+ /**
+ * Split \a line_r into fields handling also escaped separators.
+ *
+ * \see splitFields()
+ * \see splitEscaped()
+ */
+ template<class _OutputIterator>
+ unsigned splitFieldsEscaped( const C_Str & line_r,
+ _OutputIterator result_r,
+ const C_Str & sepchars_r = ":" )
+ {
+ return
+ splitEscaped( line_r, result_r, sepchars_r, true /* withEmpty */ );
+ }
+
//@}
///////////////////////////////////////////////////////////////////