I have an application which uses a Javascript-based rules engine. I need a way to convert regular straight quotes into curly (or smart) quotes. It’d be easy to just do a string.replace
for ["]
, only this will only insert one case of the curly quote.
The best way I could think of was to replace the first occurrence of a quote with a left curly quote and every other one following with a left, and the rest right curly.
Is there a way to accomplish this using Javascript?
You could replace all that preceed a word character with the left quote, and all that follow a word character with a right quote.
str = str.replace(/"(?=\w|$)/g, "“");
str = str.replace(/(?<=\w|^)"/g, "”"); // IF the language supports look-
// behind. Otherwise, see below.
As pointed out in the comments below, this doesn't take punctuation into account, but easily can:
/(?<=[\w,.?!\)]|^)"/g
[Edit:] For languages that don't support look-behind, like Javascript, as long as you replace all the front-facing ones first, you have two options:
str = str.replace(/"/g, "”"); // Replace the rest with right curly quotes
// or...
str = str.replace(/\b"/g, "”"); // Replace any quotes after a word
// boundary with right curly quotes
(I've left the original solution above in case this is helpful to someone using a language that does support look-behind)
You might want to look at what Pandoc does—apparently with the --smart
option, it handles quotes properly in all cases (including e.g. ’tis and ’twere).
I recently wrote a Javascript typography prettification engine that does, among other things, quote replacement; I wound up using basically the algorithm suggested by Renesis, but there’s currently a failing test up waiting for a smarter solution.
If you’re interested in cribbing my code (and/or submitting a patch based on work you’ve done), check it out: jsPrettify. jsprettify.prettifyStr
does what you’re looking for. If you don’t want to deal with the Closure dependency, there’s an older version that runs on its own—it even works in Rhino.
'foo "foo bar" "bar"'.replace(/"([-a-zA-Z0-9 ]+)"/g, function(wholeMatch, m1){
return "“" + m1 + "”";
});
The following just changes every quote by alternating (this specific example however would leave out the orphaned quotes).
str.replace(/\"([^\"]*)\"/gi,"“$1”");
Works perfectly, as long as the text you're texturizing isn't already screwed up with improper use of the double quote. In English, quotes are never nested.
I don't think something like that in general is easy at all, because you'd have to interpret exactly what each double-quote character in your content means. That said, what I'd do is collect all the text nodes I was interested in, and then go through and keep track of the "on/off" (or "odd/even"; whatever) nature of each double quote instance. Then you can know which replacement entity to use.
I didn't find the logic I wanted here, so here's what I ended up going with.
value = value.replace(/(^|\s)(")/g, "$1“"); // replace quotes that start a line or follow spaces
value = value.replace(/"/g, "”"); // replace rest of quotes with the back smart quote
I have a small textarea that I need to replace straight quotes with curly (smart) quotes. I'm just executing this logic on keyup. I tried to make it behave like Microsoft Word.
Posting for posterity.
As suggested by @Steven Dee, I went to Pandoc.
I try to use a mature and tested tool whenever I can versus baking my own regex. Hand built regex's can be overly greedy, or not greedy enough, and they may not be sensitive to word boundaries and commas etc. Pandoc accounts for most this and more.
From the command line (the --smart parameter turns on smart quotes):
pandoc --smart --standalone -o output.html input.html
..and I know a command line script may or may not fit OP's requirement of using Javascript. (related: How to execute shell command in Javascript)
来源:https://stackoverflow.com/questions/2202811/converting-straight-quotes-to-curly-quotes