0

I'm creating a regex that matches straight apostrophes and replaces them with a curly ones. Sometimes an apostrophe goes in the middle of two characters. Other times goes at the end of a character/word (e.g. ellipsis').

So I have two regexes that handle both situations (separated by an or statement).

However, only the first case is being replaced, not the second. In other words, this:

"Wor'd word'".replace(/(?<=\w)\'(?=\w)|(?<=\w)\'(?=\s)/, '&rsquo;') 

Becomes this:

"Wor&rsquo;d word'"

This confuses me because both types of apostrophes are matching: https://regexr.com/4td7p

Why is this, and how to fix it?

Update: I figured the problem was that there's no space after the last apostrophe, so I changed the second part of the regex to this: (?<=\w)\'(?!\w) (don't match if there's a character after the apostrophe). But I'm getting the same result.

alexchenco
  • 53,565
  • 76
  • 241
  • 413
  • 2
    You need the global flag, `/g`, else only the first occurrence will be replaced (note how the regexr link's flags contain "g", but your code's pattern doesn't) – CertainPerformance Feb 01 '20 at 08:45
  • @CertainPerformance adding the `g` doesn't work. – alexchenco Feb 01 '20 at 08:47
  • Are you trying for the last `'` to be replaced? It doesn't match because there are no characters after the `'` - lookahead fails because there are no characters ahead. You can lookahead for `\s` or the end of the string, `(?=\s|$)`. You can also put the patterns together instead of alternating, `(?<=\w)\'(?=[\s\w]|$)` – CertainPerformance Feb 01 '20 at 08:52
  • @CertainPerformance This isn't a `g` flag issue, so it's not a duplicate question. – alexchenco Feb 01 '20 at 08:52
  • @CertainPerformance Check my update. Now I'm saying: "don't match if there's a character ahead." But I'm getting the same result. – alexchenco Feb 01 '20 at 08:53

2 Answers2

1

If you want to match (?<=\w)\' followed by a character and also match (?<=\w)\' not followed by a character, why not just drop the logic after it altogether and just use (?<=\w)'? (no need to escape 's in a regex)

You also need the global flag to replace more than one thing at a time:

console.log(
  "Wor'd word'".replace(/(?<=\w)'/g, '&rsquo;')
);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thanks, but I want to know why my updated regex `(?<=\w)\'(?!\w)` is not doing the trick. – alexchenco Feb 01 '20 at 10:05
  • Oh ... my first regex wasn't working with the `g`. But my updated regex works with the `g`. – alexchenco Feb 01 '20 at 10:07
  • 1
    None of the patterns will work if there is more than one character in the string to replace *and* the `g` flag is not being used. The `g` flag is necessary to replace all matches regardless. – CertainPerformance Feb 01 '20 at 10:14
-1

updated

var str = "Wor'd word' that's a good thing'";
var afterReplace = str.replace(/'\b/g, '&rsquo;') 
console.log(afterReplace);
Abdelrahman Gobarah
  • 1,544
  • 2
  • 12
  • 29