So I got this string
'word word - word word 24/03/21'
And I would like to convert it to
'word_word-word_word_24_03_21'
I have tried this
replace(/[^aA-zZ0-9]/g, '_')
But I get this instead
word_word___word_word_24_03_21
So I got this string
'word word - word word 24/03/21'
And I would like to convert it to
'word_word-word_word_24_03_21'
I have tried this
replace(/[^aA-zZ0-9]/g, '_')
But I get this instead
word_word___word_word_24_03_21
You can use 2 .replace()
calls:
const s = 'word word - word word 24/03/21'
var r = s.replace(/\s*-\s*/g, '-').replace(/[^-\w]+/g, '_')
console.log(r)
//=> "word_word-word_word_24_03_21"
Explanation:
.replace(/\s*-\s*/g, '-')
: Remove surrounding spaces of a hyphen.replace(/[^-\w]+/g, '_')
: Replace all character that are not a hyphen and not a word character with an underscoreYou can use
console.log(
'word word - word word 24/03/21'.replace(/\s*(-)\s*|[^\w-]+/g, (x,y) => y || "_")
)
Here,
/\s*(-)\s*|[^\w-]+/g
- matches and captures into Group 1 a -
enclosed with zero or more whitespaces, and just matches any non-word char excluding -
(x,y) => y || "_")
- replaces with Group 1 if it was matched, and if not, replacement is a _
char.With a function for replace and an alternation in the pattern, you could also match:
(\s*-\s*)
Match a -
between optional whtiespace chars|
Or[^a-zA-Z0-9-]+
Match 1+ times any of the listed rangesIn the callback, check if group 1 exists. If it does, return only a -
, else return _
Note that this notation [^aA-zZ0-9]
is not the same as [a-zA-Z0-9]
, see what [A-z]
matches.
let s = "word word - word word 24/03/21";
s = s.replace(/(\s*-\s*)|[^a-zA-Z0-9-]+/g, (_, g1) => g1 ? "-" : "_");
console.log(s);
You can use the +
regex operator to replace 1 or more continuous matches at once.
let s = 'word word - word word 24/03/21';
let r = s
.replace(/[^aA-zZ0-9]*-[^aA-zZ0-9]*/g, '-')
.replace(/[^aA-zZ0-9-]+/g, '_');
console.log(r);
// 'word_word-word_word_24_03_21'