4
\$\begingroup\$

After years of fear and procrastination I decided to learn regular expressions. This is the result:

CoffeScript:

str = "<h2><a name=\"#{chapter._id}\">#{chapter.title}</a></h2>\n\n#{chapter.content}\n\n"

str.replace(/>([^>]+)</g, (r) ->
  r.replace(/(>|\s)"/g, "$1“")
   .replace(/"/g, "”")
   .replace(/("|\s)'/g, "$1‘")
   .replace(/'/g, "’")
)

JavaScript:

var str = "<h2><a name=\"" + chapter._id + "\">" + chapter.title + "</a></h2>\n\n" + chapter.content + "\n\n";

str.replace(/>([^>]+)</g, function(r) {
  return r.replace(/(>|\s)"/g, "$1“")
          .replace(/"/g, "”")
          .replace(/("|\s)'/g, "$1‘")
          .replace(/'/g, "’");
});

As you can see, the code turns all "straight" quotation characters (plus apostrophe) to “curly” ones. It was a bit hard because the input had stuff like this:

<p class="">"Yes," he said, "I met her. She's very 'friendly.'"</p>

So I had to make sure the quotes inside the HTML tags were not being included. And make the code know that quotations wouldn't always be preceded by a space (sometimes by an >).

I welcome any suggestion to make the code shorter, more efficient/readable.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This will fail on <p>"I love <i>cats<i>"</p> \$\endgroup\$ Commented Sep 19, 2016 at 21:27

1 Answer 1

3
\$\begingroup\$

Since you know that the double quotes will always be matched, you might try this instead of your first two replaces:

r.replace(/"([^"]*)"/g, "“$1”")

I think that's a little stronger. The unmatched single quotes are harder, and I think what you have is reasonable. I might try this tack though if JavaScript has the \w for word letters. (If not, use [a-zA-Z].)

.replace(/(\w)'(\w)/g, "$1’$2")
.replace(/'([^']*)'/g, "‘$1’")
\$\endgroup\$
1
  • \$\begingroup\$ This will fail on <p>"I <i>love</i> cats" he said, "but I hate dogs."</p> because it is not necessary the that matched pairs of quotes will not have any html tags inside. \$\endgroup\$ Commented Sep 19, 2016 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.