views:

223

answers:

6

Does anyone have a simple tool that can convert a non-escaped string to an escaped string?

For example, I'm trying to paste the following data into a Java String datatype:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

I manually have to add the slashes:

<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

Then I can paste into my java code:

String xml="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";

Adding the slashes gets very annoying when it's a 3MB string. I know find/replace can work in a lot of tools, but I do this so often that I need an even faster way.

This must be a common issue. What do most developers do? I'm thinking a good Emacs macro could do the trick but I didn't see anything obvious.

+3  A: 

If it's a 3MB string I would read it from a file instead of hard-coding it in the source code.

Mark Byers
Usually this is a good idea. However, the string comes from a log file that has several 3MB strings. It's basically sniffing traffic for web service calls. The tool is called Fiddler. I just need to run a few experiments, not have production code. Exporting to a file would be a major pain in this case. But, you're right, it's usually a better way to go.
User1
You only have to write the code to read from a file once, then you can just copy + paste the log extract into the file each time you want to run a new test - I'd say that's quicker than copying and pasting into a specific position in a source code file. Plus you'll have to re-escape the text every time you want to test a new string. Anyway, I probably am not going to change your mind so good luck with finding a solution. :)
Mark Byers
@Mark - agreed. Even as a once-off test, the OP's approach is a pretty lame way to do it. Surely it is only half a dozen lines of Java code to read text from a file. Or one line if you use something like this: http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html#readFileToString(java.io.File)
Stephen C
It certainly is a balance. The overhead of saving information to another throw-away file, making sure it actually overwrote old data, and keeping the pathname and permissions straight is a hassle I like to avoid. A big old String in Java is ugly too, especially since Java String constants are not friendly to new lines like most C compilers.
User1
+2  A: 

Regular expressions.

s/(?=["\\])/\\/g

You can fill in the character class with any other characters you want escaped.

Anon.
That's not sufficient for full XML protection, which he or she may or may not need.
bmargulies
XML protection doesn't seem necessary. From my reading of the problem, all that's needed is escaping the string literal so that the Java compiler interprets it correctly.
Anon.
It would be nice to have full XML protection. However, I don't need it in this case.
User1
What about the new lines? When I try this on more than one line I get an error 'unclosed string literal'.
Mark Byers
Huh. I guess I'm used to environments where multiline string literals are allowed. Just run another regex over it, then: `s/\n/\\n/g`
Anon.
A: 

Apache Betwixt includes a utility function for this purpose, here.

bmargulies
Very interesting. Any idea how I can make a tool from this method?
User1
Write a program to call it? I don't understand the difficulty.
bmargulies
A: 

In support of @Mark Bayer's answer, here is a one-liner for reading the contents of a file into a String.

String s = org.apache.commons.io.FileUtils.readFileToString("someFile");

Here's the Javadoc for the Apache Commons FileUtils class.

And you can trivially implement the equivalent functionality from scratch; e.g.

StringBuilder sb = new StringBuilder();
Reader r = new BufferedReader(new FileReader("somefile"));
try {
    int ch;
    while ((ch = r.read()) != -1) {
       sb.append((char) ch);
    }
} finally {
    r.close();
}
String s = sb.toString();

Embedding monstrously large strings into source code ... even as a throw away test ... is so lame.

Stephen C
+1  A: 

Take a look at prin1-to-string.

For example, invoking the following command will insert/paste the most recently killed/saved/cut text as escaped-string:

(defun yank-escaped-string ()
  (interactive)
  (insert (prin1-to-string (substring-no-properties (current-kill 0)))))

Bear in mind that the escaping mechanism is for producing strings to be read by Elisp, with conventions that might be similar to your target but not exactly the same.

huaiyuan
+1  A: 

StringEscapeUtils is really good

Sri Kumar