Here's my code for solving the problem. Very much welcome improvements.
package my.package;
public class ParseableStringHelper {
/**
* http://stackoverflow.com/questions/1029897/comparing-a-char-to-a-code-
* point
*
* Does not implement Iterator
*/
static class CodePointIterator {
private final String sequence;
private int index = 0;
public CodePointIterator(final String sequence) {
this.sequence = sequence;
}
public boolean hasNext() {
return index < sequence.length();
}
public int next() {
int codePoint = sequence.codePointAt(index);
index += Character.charCount(codePoint);
return codePoint;
}
}
/**
* Converts a String to a version that can be parsed by a C or Java compiler
* when enclosed in double quotes, which requires escaping all special
* characters by prefixing them with a backslash. Does NOT do anything
* special for single-quote characters (which are perfectly valid inside a
* quoted string); always escapes double-quote characters.
*
* http://docs.oracle.com/javase/tutorial/java/data/characters.html
*
* @param internal
* String that may have special characters
* @return String with proper escape sequences for special characters like
* backslash and newline.
*/
public static String getParseableVersion(final String internal) {
StringBuilder sb = new StringBuilder();
CodePointIterator pointIterator = new CodePointIterator(internal);
while (pointIterator.hasNext()) {
int point = pointIterator.next();
switch (point) {
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
case '\\':
// double these up
sb.append("\\\\");
break;
case '"':
sb.append("\"");
break;
default:
sb.append(Character.toChars(point));
break;
}
}
return sb.toString();
}
/**
* Test the helper
*
* @param args
*/
public static void main(String[] args) {
String[] tests = { "C:\\Temp\\file.txt",
"This has\tsome special characters\n" };
for (String t : tests)
System.out.println("Orig is " + t + ", parseable is \""
+ getParseableVersion(t) + "\"");
}
}