fork download
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <regex>
  4. #include <string>
  5. #include <vector>
  6.  
  7. namespace boris {
  8.  
  9. namespace JSONPrettify_specifics{
  10. enum class Colons{
  11. TIGHT,
  12. SPACED
  13. };
  14. enum class Position{
  15. TAB = 0,
  16. COMMA = 1,
  17. OBJ_START = 2,
  18. OBJ_END = 3,
  19. ARRAY_START = 4,
  20. ARRAY_END = 5
  21. };
  22. struct RegexPos{
  23. size_t pos;
  24. long length;
  25. };
  26.  
  27. std::string generateSpaces( int l ){
  28. return std::string(l*4, ' ');
  29. }
  30. long lowestOf( std::vector<size_t> of ){
  31. std::vector<size_t>::iterator result = std::min_element(std::begin(of), std::end(of));
  32. return std::distance(std::begin(of), result);
  33. }
  34.  
  35. void insertColonSpaces( std::string & j ){
  36. std::regex colon = std::regex(R"(\s*?\:\s*?(?=\S))");
  37. j.assign(std::regex_replace(j, colon, " : "));
  38. }
  39. RegexPos findRegexFirstPosition( const std::string & json, const long start_pos, const std::regex rx ){
  40. size_t at = -1;
  41. long l = 0;
  42.  
  43. std::string ss( json.begin()+start_pos, json.end() );
  44. std::smatch m;
  45.  
  46. std::regex_search( ss, m, rx );
  47.  
  48. if ( m.size() > 0 ) {
  49. at = m.position(0);
  50. l = m[0].str().size();
  51. }
  52. if( at < json.size() ) at += start_pos;
  53. return {at,l};
  54. }
  55. }
  56.  
  57. std::string JSONPrettify( const std::string & json, boris::JSONPrettify_specifics::Colons spacing=boris::JSONPrettify_specifics::Colons::TIGHT ){
  58.  
  59. using namespace boris::JSONPrettify_specifics;
  60.  
  61. std::string pretty = json;
  62. const std::regex var = std::regex(R"((\".+?\".*?(?=\{|\[|\,|\]|\}))|(\d+?))");
  63.  
  64. long it = 0;
  65. int depth = 0;
  66.  
  67. while( it < pretty.size() ){
  68.  
  69. RegexPos pos_tab = findRegexFirstPosition( pretty,it, var );
  70. auto pos_comma = pretty.find( ",", it );
  71. auto pos_obj_start = pretty.find( "{", it );
  72. auto pos_obj_end = pretty.find( "}", it );
  73. auto pos_array_start = pretty.find( "[", it );
  74. auto pos_array_end = pretty.find( "]", it );
  75.  
  76. long old_it = it;
  77.  
  78. Position work_with = static_cast<Position>(lowestOf({ pos_tab.pos, pos_comma, pos_obj_start, pos_obj_end,pos_array_start,pos_array_end }));
  79.  
  80. switch( work_with ){
  81.  
  82. case(Position::TAB):{
  83. std::string insert = generateSpaces(depth);
  84.  
  85. pretty.insert( pos_tab.pos, insert );
  86.  
  87. it = pos_tab.pos+insert.size()+pos_tab.length;
  88. break;
  89. }
  90.  
  91. case(Position::COMMA):{
  92. std::string insert = "\n";
  93.  
  94. pretty.insert( pos_comma+1, insert );
  95.  
  96. it = pos_comma+1;
  97. break;
  98. }
  99.  
  100. case(Position::OBJ_START):{
  101. std::string insert = "\n";
  102. pretty.insert( pos_obj_start+1, insert );
  103.  
  104. it = pos_obj_start+insert.size();
  105.  
  106. depth+=1;
  107.  
  108. if(pos_obj_start-1 > pretty.size()) continue;
  109.  
  110. if(pretty.at(pos_obj_start-1) != ':'){
  111. std::string extra = generateSpaces( depth-1 );
  112. pretty.insert( pos_obj_start, extra );
  113. it+=extra.size();
  114. }
  115.  
  116. break;
  117. }
  118.  
  119. case(Position::OBJ_END):{
  120. std::string insert = "\n"+generateSpaces( depth-1 );
  121. pretty.insert( pos_obj_end, insert );
  122.  
  123. it = pos_obj_end+insert.size()+1;
  124.  
  125. depth-=1;
  126. break;
  127. }
  128.  
  129. case(Position::ARRAY_START):{
  130. std::string insert = "\n";
  131. pretty.insert( pos_array_start+1,insert );
  132. it=pos_array_start+insert.size();
  133.  
  134. depth+=1;
  135. break;
  136. }
  137.  
  138. case(Position::ARRAY_END):{
  139. std::string insert = "\n"+generateSpaces( depth-1 );
  140. pretty.insert( pos_array_end,insert );
  141. it=pos_array_end+insert.size()+1;
  142.  
  143. depth-=1;
  144. break;
  145. }
  146.  
  147. default:{
  148. break;
  149. }
  150. };
  151.  
  152. if(it == old_it)
  153. break;
  154. }
  155.  
  156. if(spacing == Colons::TIGHT)
  157. insertColonSpaces(pretty);
  158.  
  159. return pretty;
  160. }
  161. };
  162.  
  163. int main() {
  164. std::cout << boris::JSONPrettify("abc") ;
  165. }
Runtime error #stdin #stdout #stderr 0s 3500KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::insert: __pos (which is 4294967295) > this->size() (which is 3)