let text = "’I’m the cook,’ he said, ‘it’s my job.’";
Console.log(text.replace(/(^|W)’|'(W|$)/g, ‘$1"$2’));
This code was meant to convert single quotes in sentences into double quotes without affecting single quotes used in contractions like aren’t
I understand the or statements and everything, even the pipe character. I just don’t understand how the capturing and replacement is done for each single quote. For every single quote that is replaced, what is the value of $1 and $2. Am confused?
I understand the regular expression used. I just don’t understand fully how it executes in this particular scenario.
At first it checks for if any beginning of line(^) proceeds a single quote. It finds one in the first word (‘I’m). So let’s say the first capture is the ^ indicating beginning of a line. So $1 is an empty space. Now I dnt get how it gets $2. Because I know it has to get $2 so it can place double quotes in between them to get $1"$2.
2
Answers
I realize you said you understood the expression, but just for clarity
/(^|W)'|'(W|$)/
is an alternation between two (outer) alternatives:(^|W)'
and'(W|$)
. Each match will match one or the other of those subexpressions (which are also alternations, but that’s not important here). Since the alternatives have capture groups in them, that means that one of the groups will have something in it, and the other won’t, since only one alternative can match. When you give thereplace
method a replacement string with placeholders like$1
and$2
, it’ll use a blank string for a capture group that has no value.To see exactly what the groups end up containing, you can pass a replacement function to
replace
instead of a replacement string. The function will receive the complete match as its first argument, the first capture group as its second argument, the second capture group as its third argument, etc.; the replacement is whatever the function returns. So if you swap the replacment string for a replacement function, you can use the debugger to look at the values of (in the below)c1
andc2
(or log them out as I have in the snippet below). Unlike when you givereplace
a replacement string, though, when you give it a function it’ll give you the valueundefined
(not a blank string) for a capture group that has no value, so we’ll need to handle that in our function.Here’s an example of doing that:
Both
$1
and$2
will always exist for that expression, and will be treated as a zero-length string for uncaptured values. Let’s look at the results of a slightly modified version using a sentence that uses both capture groups.It replaces all the relevant matches with info contained in square brackets, which happens in four different places.
When both matches are taken together, you’ll always end up with one captured match and one empty match. So, the sequence
$1"$2
will always fill in both$1
and$2
with a quotation mark between them but it’s guaranteed that one of those two captures will be empty.