55265

How to parse a string with raw escape sequences?

Question:

Suppose there are 2 strings:

string parse(const string& s) { // how to write this function? } int main() { string s1 = R"(hello\n\"this is a string with escape sequences\"\n)"; string s2 = "hello\n\"this is a string with escape sequences\"\n"; assert(parse(s1) == s2); }

My question is, how to write the function parse() in order to make the assertion succeed, other than some hand-made code traversing the string and checking against every possible escape sequence? Is there any existing idiom for doing this?

Answer1:

It's probably the easiest to just implement the replacement of escape sequences using a regular expression, but if you insist on doing it without, you can always write the string to a file as part of a valid C++ program that prints the string to a file, then read it from the file. (This can also be improved to work without temp files at all)

#include <iostream> #include <fstream> #include <string> #include <cstdlib> #include <assert.h> using std::string; string parse(const string& s) { std::ofstream ftmp("tmpsrc.cpp"); ftmp << "#include <iostream>\nint main(int argc, char* argv[]){\n"; ftmp << " std::cout << \"" << s << "\";\nreturn 0;}\n\n"; ftmp.close(); system("g++ -o tmpprint tmpsrc.cpp"); system("./tmpprint > tmpstr.txt"); std::ifstream fin("tmpstr.txt",std::ios::in|std::ios::binary); fin.seekg(0,std::ios::end); int size=fin.tellg(); fin.seekg(0); string res; res.resize(size); fin.read(&res[0],size); fin.close(); // Add delete of temp files here return res; } int main() { string s1 = R"(hello\n\"this is a string with escape sequences\"\n)"; string s2 = "hello\n\"this is a string with escape sequences\"\n"; assert(parse(s1) == s2); }

Answer2:

IMHO, C++ escape sequencies are very easy to replace them manually

string string_replace( const string & s, const string & findS, const std::string & replaceS ) { string result = s; auto pos = s.find( findS ); if ( pos == string::npos ) { return result; } result.replace( pos, findS.length(), replaceS ); return string_replace( result, findS, replaceS ); } string parse(const string& s) { static vector< pair< string, string > > patterns = { { "\\\\" , "\\" }, { "\\n", "\n" }, { "\\r", "\r" }, { "\\t", "\t" }, { "\\\"", "\"" } }; string result = s; for ( const auto & p : patterns ) { result = string_replace( result, p.first, p.second ); } return result; } int main() { string s1 = R"(hello\n\"this is a string with escape sequences\"\n)"; string s2 = "hello\n\"this is a string with escape sequences\"\n"; cout << parse(s1) << endl; cout << ( parse(s1) == s2 ) << endl; }

Output:

<blockquote>

hello "this is a string with escape sequences"

1

</blockquote>

<a href="http://ideone.com/jMAfRK" rel="nofollow">http://ideone.com/jMAfRK</a>

Answer3:

You could use string stream. Check each character of the string for an escaped backslash '\' character. When found, check for the next character to be a valid escape character. Then write a string to the string stream for that escape character sequence.

std::string parse(const std::string& s) { std::stringstream ss{""}; for(size_t i = 0; i < s.length(); i++) { if (s.at(i) == '\\') { switch(s.at(i + 1)) { case 'n': ss << "\n"; i++; break; case '"': ss << "\""; i++; break; default: ss << "\\"; break; } } else { ss << s.at(i); } } return ss.str(); }

Recommend

  • Permissions error when using cli in Jboss wildfly and docker
  • Python script in a browser
  • Why use CDN(Content Delivery Network‎)? [duplicate]
  • applying background to first, and every third row in a dynamically generated table
  • How do I chomp a string if I have Perl 4?
  • javascript Confirm replacement with return true/false
  • Insert space after period using sed
  • Recursion Control flow
  • Raphael.js function getBBox give back NAN/NAN/NAN in IE8
  • matching similar elements in between two lists
  • Use sed with regex and (
  • IE10 strips out hashtag from the URL
  • Create a link to a web page that runs a Javascript function on the page
  • NSIS decompiler
  • How to 'create temp table as select' in Slick?
  • How load cv2.KeyPoint and Descriptors correctly on OpenCV 3 with Python 3?
  • In-place sed command not working
  • NUnit 3.0 TestCase const custom object arguments
  • Plotting line graph with factors in R
  • Memory error in python- how to use more memory
  • Differences in dis-assembled C code of GCC and Borland?
  • Appending Character to Character Array In C
  • Can you perform a UNION without a subquery in SQLAlchemy?
  • Algorithm for a smudge tool?
  • FFmpeg Conversion Error
  • Paperclip, set path outside of rails root folder
  • Do create extension work in single-user mode in postgres?
  • R: gsub and capture
  • How to pass list parameters for each object using Spring MVC?
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • How do I rollback to a specific git commit
  • Is there a mandatory requirement to switch app.yaml?
  • Comma separated Values
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • SQL merge duplicate rows and join values that are different
  • LevelDB C iterator
  • Can't mass-assign protected attributes when import data from csv file
  • Checking variable from a different class in C#
  • Busy indicator not showing up in wpf window [duplicate]
  • How to load view controller without button in storyboard?