2
2
3
3
public class EscapeProcessor {
4
4
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
+
5
9
private final String inputString ;
6
10
private boolean inQuotes = false ;
7
11
private StringBuilder escapedJson ;
12
+
8
13
public EscapeProcessor (String inputString ) {
9
14
this .inputString = inputString ;
10
15
}
16
+
17
+
11
18
public String process () {
12
19
escapedJson = new StringBuilder ();
13
20
inQuotes = false ;
14
21
for (int i = 0 ; i < inputString .length (); i ++) {
15
22
char currentChar = inputString .charAt (i );
16
23
if (currentChar != '\"' ) {
17
- processForNonQuoteCharacter (currentChar );
18
- continue ;
24
+ handleNonQuoteCharacter (currentChar );
25
+ }
26
+ else {
27
+ handleQuoteCharacter (currentChar , i );
19
28
}
20
- processQuoteCharacter (currentChar , i );
21
29
}
22
30
return escapedJson .toString ();
23
31
}
24
32
25
- private void processQuoteCharacter (char currentChar , int i ) {
33
+ private void handleQuoteCharacter (char currentChar , int i ) {
26
34
if (!inQuotes ) {
27
35
inQuotes = true ;
28
36
escapedJson .append (currentChar );
@@ -33,39 +41,52 @@ private void processQuoteCharacter(char currentChar, int i) {
33
41
escapedJson .append (currentChar );
34
42
return ;
35
43
}
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 );
46
46
return ;
47
47
}
48
48
escapedJson .append ('\\' );
49
49
escapedJson .append (currentChar );
50
50
}
51
51
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
+
52
73
private int getNextValidCharPosition (int position ) {
53
74
for (int i = position ; i < inputString .length (); i ++) {
54
75
char currentChar = inputString .charAt (i );
55
- if (currentChar != ' ' && currentChar != '\n' && currentChar != '\t' ) {
76
+ if (currentChar != SPACE_CHAR && currentChar != BREAK_LINE_CHAR && currentChar != TAB_CHAR ) {
56
77
return i ;
57
78
}
58
79
}
59
80
return -1 ;
60
81
}
61
82
62
83
63
- private void processForNonQuoteCharacter (char currentChar ) {
84
+ private void handleNonQuoteCharacter (char currentChar ) {
64
85
if (!inQuotes ) {
65
86
escapedJson .append (currentChar );
66
87
return ;
67
88
}
68
- if (currentChar == '\t' || currentChar == '\n' ) {
89
+ if (currentChar == TAB_CHAR || currentChar == BREAK_LINE_CHAR ) {
69
90
escapedJson .append (getEscapeSequence (currentChar ));
70
91
return ;
71
92
}
@@ -74,8 +95,8 @@ private void processForNonQuoteCharacter(char currentChar) {
74
95
75
96
private String getEscapeSequence (char currentChar ) {
76
97
return switch (currentChar ) {
77
- case '\t' -> "\\ t" ;
78
- case '\n' -> "\\ n" ;
98
+ case TAB_CHAR -> "\\ t" ;
99
+ case BREAK_LINE_CHAR -> "\\ n" ;
79
100
default -> "" ;
80
101
};
81
102
}
@@ -91,7 +112,7 @@ private boolean isValidCloseQuote(int i) {
91
112
private char findNextValidChar (int position ) {
92
113
for (int i = position ; i < inputString .length (); i ++) {
93
114
char currentChar = inputString .charAt (i );
94
- if (currentChar != ' ' && currentChar != '\n' && currentChar != '\t' ) {
115
+ if (currentChar != SPACE_CHAR && currentChar != BREAK_LINE_CHAR && currentChar != TAB_CHAR ) {
95
116
return currentChar ;
96
117
}
97
118
}
0 commit comments