Sara
Sara

Reputation: 45

Replace multiple characters by one character with regex

I have this string :

var str = '#this #is____#a test###__'

I want to replace all the character (#,_) by (#) , so the excepted output is :

'#this #is#a test#'

Note : I did not knew How much sequence of (#) or (_) in the string

what I try :

I try to write :

var str = '#this #is__ __#a test###__'
str = str.replace(/[#_]/g,'#')
alert(str)

But the output was :

#this #is## ###a test#####

my try online

I try to use the (*) for sequence But did not work :

var str = '#this #is__ __#a test###__'
str = str.replace(/[#_]*/g,'#')
alert(str)

so How I can get my excepted output ?

Upvotes: 5

Views: 7026

Answers (3)

user3310334
user3310334

Reputation:

You should use the + to match one-or-more occurrences of the previous group.

var str = '#this #is__ __#a test###__'
str = str.replace(/[#_]+/g,'#')
alert(str)

Upvotes: 0

Loris Topa
Loris Topa

Reputation: 91

A well written RegEx can handle your problem rather easily. Quoting Mohit's answer to have a startpoint:

var str = '#this #is__ __#a test###__';
var formattedStr = str.replace(/[#_,]+/g, '#');
console.log( formattedStr );

Line 2:
Put in formattedStr the result of the replace method on str.
How does replace work? The first parameter is a string or a RegEx.
Note: RegExps in Javascripts are Objects of type RegExp, not strings. So writing

/yourRegex/

or

New RegExp('/yourRegex/')

is equivalent syntax. Now let's discuss this particular RegEx itself.
The leading and trailing slashes are used to surround the pattern, and the g at the end means "globally" - do not stop after the first match.
The square parentheses describe a set of characters who can be supplied to match the pattern, while the + sign means "1 or more of this group".
Basically, ### will match, but also # or #####_# will, because _ and # belong to the same set.
A preferred behavior would be given by using (#|_)+
This means "# or _, then, once found one, keep looking forward for more or the chosen pattern".
So ___ would match, as well as #### would, but __## would be 2 distinct match groups (the former being __, the latter ##).
Another problem is not knowing wheter to replace the pattern found with a _ or a #.
Luckily, using parentheses allows us to use a thing called capturing groups. You basically can store any pattern you found in temporary variabiles, that can be used in the replace pattern.
Invoking them is easy, propend $ to the position of the matched (pattern).
/(foo)textnotgetting(bar)captured(baz)/ for example would fill the capturing groups "variables" this way:

$1 = foo
$2 = bar
$3 = baz

In our case, we want to replace 1+ characters with the first occurrence only, and the + sign is not included in the parentheses!
So we can simply

str.replace("/(#|_)+/g", "$1");

In order to make it work.

Have a nice day!

Upvotes: 6

Mohit Bhardwaj
Mohit Bhardwaj

Reputation: 10093

Your regex replaces single instance of any matched character with character that you specified i.e. #. You need to add modifier + to tell it that any number of consecutive matching characters (_,#) should be replaced instead of each character individually. + modifier means that 1 or more occurrences of specified pattern is matched in one go. You can read more about modifiers from this page:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

var str = '#this #is__ __#a test###__';
var formattedStr = str.replace(/[#_,]+/g, '#');
console.log( formattedStr );

Upvotes: 1

Related Questions