1

I'm still new in regex and still learning. But struggle to achieve this one.

What I want from here is to change a specific number with this format:

(space)(number)(space) or (space)(number)(word)

This is my current code:

let initial = "Sample 50 This 500是是 50是 of 50是. Sample 450是是";
let regex = new RegExp("\\b50|\\b50\\D", "g");
let result = initial.replace(regex, "9");
console.log(result);

So from this string:

Sample 50 This 500是是 50是 of 50是. Sample 450是是

The result should be this one:

Sample 9 This 500是是 9是 of 9是. Sample 450是是

But my current result is this (500 also changed):

Sample 9 This 90是是 9是 of 9是. Sample 450是是

Is this possible? Thanks for the help.

Pepeng Hapon
  • 357
  • 1
  • 17

2 Answers2

1

The problem with your current pattern is that the left-side alternation \b50 will match 50 even if there are more adjacent digits immediately to the right of the 50 - which you want to make sure there aren't.

After matching the number, negative lookahead for a digit:

\b50(?!\d)

replace with 9:

const input = "Sample 50 This 500是是 50是 of 50是. Sample 450是是";
console.log(
  input.replace(
    /\b50(?!\d)/g,
    '9'
  )
);

Note that since you aren't constructing the pattern dynamically, there's no need for new RegExp - use a regex literal instead, so you don't have to double-escape the backslashes (which make it harder to read).

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Hi @CertainPerformance, your solution works great and It has a readable code. I have noted the additional link you've added. Many thanks for the info. One quesiton, where can I find to read the docu about this one: !\d 'cause what I know is that the counterpart of \d is \D – Pepeng Hapon Aug 11 '19 at 05:10
  • `(?!` is the syntax for negative lookahead. Eg `foo(?!x)` will match `foo` in `fooa`, but not `foo` in `foox`. Negative lookahead for `\d` and *matching* `\D` like you're doing are pretty similar - both ensure that what was matched before isn't followed by a digit, but `\D` will mean that the non-digit character is matched as well (eg all characters in`50是` will be matched, but you only want to match the `50` part, because that's the only part you want to replace). – CertainPerformance Aug 11 '19 at 05:14
1

You can use this

(\D|^)50(\D|$)
  • (\D|^) - Match Non digit character or start of string ( group1 -> $1 )
  • 50 - Match 50
  • (\D|$) - Match Non digit character or end of string ( group2 -> $2 )

let initial = "50Sample 50 This 500是是 50是 of 50是. Sample 450是是50";
let regex = /(\D|^)50(\D|$)/g
let result = initial.replace(regex, "$19$2");
console.log(result);
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • Hi @Code Maniac, your solutions works! But CertainPerformance made the first answer. But I upvoted your answer. One question though, what is the meaning of "$19$2"? Appreciated your help. Thank you! – Pepeng Hapon Aug 11 '19 at 05:07
  • @PepengHapon always happy to help, `$1` -> back reference to group one, `$2` back reference to group two, so this actually means `place captured value of group one 9 place captured value of group 2` – Code Maniac Aug 11 '19 at 05:11