22
33public class EscapeProcessor {
44 private static final char EOF = '\0' ;
5+ private static final char TAB_CHAR = '\t' ;
6+ private static final char BREAK_LINE_CHAR = '\n' ;
7+ private static final char SPACE_CHAR = ' ' ;
8+
59 private final String inputString ;
610 private boolean inQuotes = false ;
711 private StringBuilder escapedJson ;
12+
813 public EscapeProcessor (String inputString ) {
914 this .inputString = inputString ;
1015 }
16+
17+
1118 public String process () {
1219 escapedJson = new StringBuilder ();
1320 inQuotes = false ;
1421 for (int i = 0 ; i < inputString .length (); i ++) {
1522 char currentChar = inputString .charAt (i );
1623 if (currentChar != '\"' ) {
17- processForNonQuoteCharacter (currentChar );
18- continue ;
24+ handleNonQuoteCharacter (currentChar );
25+ }
26+ else {
27+ handleQuoteCharacter (currentChar , i );
1928 }
20- processQuoteCharacter (currentChar , i );
2129 }
2230 return escapedJson .toString ();
2331 }
2432
25- private void processQuoteCharacter (char currentChar , int i ) {
33+ private void handleQuoteCharacter (char currentChar , int i ) {
2634 if (!inQuotes ) {
2735 inQuotes = true ;
2836 escapedJson .append (currentChar );
@@ -33,39 +41,52 @@ private void processQuoteCharacter(char currentChar, int i) {
3341 escapedJson .append (currentChar );
3442 return ;
3543 }
36- if (findNextValidChar (i + 1 ) == '\"' ) {
37- int nextValidCharPosition = getNextValidCharPosition (i + 1 );
38- if (isValidCloseQuote (nextValidCharPosition )) {
39- escapedJson .append ('\\' );
40- escapedJson .append (currentChar );
41- return ;
42- }
43- inQuotes = false ;
44- escapedJson .append (currentChar );
45- escapedJson .append (',' );
44+ if (hasNextQuoteRightAfterCurrentQuoteWithoutComma (i + 1 )) {
45+ handleQuoteNextToQuoteCase (currentChar , i );
4646 return ;
4747 }
4848 escapedJson .append ('\\' );
4949 escapedJson .append (currentChar );
5050 }
5151
52+ private void handleQuoteNextToQuoteCase (char currentChar , int i ) {
53+ int nextQuotePosition = getNextValidCharPosition (i + 1 );
54+ // If next valid quote is a good close quote, then the current quote MUST be an escaped quote
55+ if (isValidCloseQuote (nextQuotePosition )) {
56+ escapedJson .append ('\\' );
57+ escapedJson .append (currentChar );
58+ }
59+ else {
60+ // If the next valid quote is not a good close quote, then the current quote should be a good close quote
61+ // However, the current quote and the next quote is next to each other (without separation by a comma),
62+ // we need to add a comma in between
63+ inQuotes = false ;
64+ escapedJson .append (currentChar );
65+ escapedJson .append (',' );
66+ }
67+ }
68+
69+ private boolean hasNextQuoteRightAfterCurrentQuoteWithoutComma (int position ) {
70+ return findNextValidChar (position + 1 ) == '\"' ;
71+ }
72+
5273 private int getNextValidCharPosition (int position ) {
5374 for (int i = position ; i < inputString .length (); i ++) {
5475 char currentChar = inputString .charAt (i );
55- if (currentChar != ' ' && currentChar != '\n' && currentChar != '\t' ) {
76+ if (currentChar != SPACE_CHAR && currentChar != BREAK_LINE_CHAR && currentChar != TAB_CHAR ) {
5677 return i ;
5778 }
5879 }
5980 return -1 ;
6081 }
6182
6283
63- private void processForNonQuoteCharacter (char currentChar ) {
84+ private void handleNonQuoteCharacter (char currentChar ) {
6485 if (!inQuotes ) {
6586 escapedJson .append (currentChar );
6687 return ;
6788 }
68- if (currentChar == '\t' || currentChar == '\n' ) {
89+ if (currentChar == TAB_CHAR || currentChar == BREAK_LINE_CHAR ) {
6990 escapedJson .append (getEscapeSequence (currentChar ));
7091 return ;
7192 }
@@ -74,8 +95,8 @@ private void processForNonQuoteCharacter(char currentChar) {
7495
7596 private String getEscapeSequence (char currentChar ) {
7697 return switch (currentChar ) {
77- case '\t' -> "\\ t" ;
78- case '\n' -> "\\ n" ;
98+ case TAB_CHAR -> "\\ t" ;
99+ case BREAK_LINE_CHAR -> "\\ n" ;
79100 default -> "" ;
80101 };
81102 }
@@ -91,7 +112,7 @@ private boolean isValidCloseQuote(int i) {
91112 private char findNextValidChar (int position ) {
92113 for (int i = position ; i < inputString .length (); i ++) {
93114 char currentChar = inputString .charAt (i );
94- if (currentChar != ' ' && currentChar != '\n' && currentChar != '\t' ) {
115+ if (currentChar != SPACE_CHAR && currentChar != BREAK_LINE_CHAR && currentChar != TAB_CHAR ) {
95116 return currentChar ;
96117 }
97118 }
0 commit comments