Replace a string fails in some cases - javascript

I must check a string and replace something of them.
I have to check if
$mystring='abc...';
has one of this values px,em,%,vh,s
I use this to check the string
function replaceUnit(input){ return input.replace(/(px|em|%|vh|s)/i ,'') }
It works but produces error in some cases.
If I have in my string for example
$mystring="its embeded"
The function will replace the "s" and "em" that's not the way it should be.
The function should check if in mystring is
only a number+px
or only a number+em
or only a number+%
or only a number+vh
or only a number+s
If there is a match, the function should replace the textpart, in all other cases the function should do nothing.
Is it possible to create a kind of this function and how a replace code must be?
Thanks a lot.
UPDATE
based on one of the answears i trie to change it
var input="0s";
function replaceUnit(input)
{
console.log('check: '+input);
var test=input.replace(/(\d)(?:px|em|%|vh|s)$/i ,'');
console.log('->: '+test);
return test
}
the result in the console is
check: 0s
->:

Add a $ (end-of-string anchor) to the end of the regular expression, to ensure that it'll only match if the characters occur at the very end, and capture a number before those characters, so that you can replace with that number alone (thus stripping out the extra characters):
return input.replace(/(\d)(?:px|em|%|vh|s)$/i ,'$1')
https://regex101.com/r/IodB6z/1

Related

Javascript - remove repeating characters when there are more than 2 repeats

As what the title says. When there are more than 2 repeats of a letter in a string, the excess repeats are removed.
I have the following code based off this answer but it does not seem to work:
function removeRepeatingLetters (text) {
return text.replace('^(?!.*([A-Za-z0-9])\1{2})(?=.*[a-z])(?=.*\d)[A-Za-z0-9]+$', '');
}
But it does not seem to work for my test string:
"bookkeepers! are amaazing! loooooooool"
The output for the sample string should be:
"bookkeepers! are amaazing! lool"
What am I doing wrong?
Try
"bookkeepers! are amaazing! loooooooool".replace(/(.)\1{2,}/g, '$1$1')
// "bookkeepers! are amaazing! lool"
The RegExp /(.)\1{2,}/ matches any single character followed by the same character two or more times.
The flag g ensures you match all occurrences.
Then, you replace each occurrence with the repeated character duplicated.
Note that the simpler .replace(/(.)\1+/g, '$1$1') should work too, but a bit slower because it does unnecessary replacements.
Another way (Oriol's answer works just fine) to do this is with a callback function:
function removeRepeatingLetters (text) {
return text.replace(/(.)\1{2,}/g, function(match, p1) {
return p1 + p1;
});
}
This will:
match an instances of an individual character repeated at least one - (.)\1{2,}
then it will pass the match and the first substring into a callback function - function(match, p1)
then it will return the first matched substring, appended to itself, as the value to replace the overall match - return p1 + p1;
Because of the g at the end of the regex, it will do it with all instances that it finds of repeated characters.
The above code works with the test string that you provided (along with a couple of others that I tested with ;) ). As mentioned, Oriol's works, but figured I'd share another option, since it gives you a glimpse into how to use the callback for .replace().

JS / RegEx to remove characters grouped within square braces

I hope I can explain myself clearly here and that this is not too much of a specific issue.
I am working on some javascript that needs to take a string, find instances of chars between square brackets, store any returned results and then remove them from the original string.
My code so far is as follows:
parseLine : function(raw)
{
var arr = [];
var regex = /\[(.*?)]/g;
var arr;
while((arr = regex.exec(raw)) !== null)
{
console.log(" ", arr);
arr.push(arr[1]);
raw = raw.replace(/\[(.*?)]/, "");
console.log(" ", raw);
}
return {results:arr, text:raw};
}
This seems to work in most cases. If I pass in the string [id1]It [someChar]found [a#]an [id2]excellent [aa]match then it returns all the chars from within the square brackets and the original string with the bracketed groups removed.
The problem arises when I use the string [id1]It [someChar]found [a#]a [aa]match.
It seems to fail when only a single letter (and space?) follows a bracketed group and starts missing groups as you can see in the log if you try it out. It also freaks out if i use groups back to back like [a][b] which I will need to do.
I'm guessing this is my RegEx - begged and borrowed from various posts here as I know nothing about it really - but I've had no luck fixing it and could use some help if anyone has any to offer. A fix would be great but more than that an explanation of what is actually going on behind the scenes would be awesome.
Thanks in advance all.
You could use the replace method with a function to simplify the code and run the regexp only once:
function parseLine(raw) {
var results = [];
var parsed = raw.replace(/\[(.*?)\]/g, function(match,capture) {
results.push(capture);
return '';
});
return { results : results, text : parsed };
}
The problem is due to the lastIndex property of the regex /\[(.*?)]/g; not resetting, since the regex is declared as global. When the regex has global flag g on, lastIndex property of RegExp is used to mark the position to start the next attempt to search for a match, and it is expected that the same string is fed to the RegExp.exec() function (explicitly, or implicitly via RegExp.test() for example) until no more match can be found. Either that, or you reset the lastIndex to 0 before feeding in a new input.
Since your code is reassigning the variable raw on every loop, you are using the wrong lastIndex to attempt the next match.
The problem will be solved when you remove g flag from your regex. Or you could use the solution proposed by Tibos where you supply a function to String.replace() function to do replacement and extract the capturing group at the same time.
You need to escape the last bracket: \[(.*?)\].

Regex equivalent to str.substr(0, str.indexOf('foo'))

Given this string:
var str = 'A1=B2;C3,D0*E9+F6-';
I would like to retrieve the substring that goes from the beginning of the string up to 'D0*' (excluding), in this case:
'A1=B2;C3,'
I know how to achieve this using the combination of the substr and indexOf methods:
str.substr(0, str.indexOf('D0*'))
Live demo: http://jsfiddle.net/simevidas/XSu22/
However, this is obviously not the best solution since it contains a redundancy (the str name has to be written twice). This redundancy can be avoided by using the match method together with a regular expression that captures the substring:
str.match(/???/)[1]
Which regular expression literal do we have to pass into match to ensure that the correct substring is returned?
My guess is this: /(.*)D0\*/ (and that works), but my experience with regular expressions is rather limited, so I'm going to need a confirmation...
Try this:
/(.*?)D0\*/.exec(str)[1]
Or:
str.match(/(.*?)D0\*/)[1]
DEMO HERE
? directly following a quantifier makes the quantifier non-greedy (makes it match minimum instead of maximum of the interval defined).
Here's where that's from
/^(.+?)D0\*/
Try it here: http://rubular.com/r/TNTizJLSn9
/^.*(?=D0\*)/
more text to hit character limit...
You can do a number-group, like your example.
/^(.*?)foo/
It mean somethink like:
Store all in group, from start (the 0)
Stop, but don't store on found foo (the indexOf)
After that, you need match and get
'hello foo bar foo bar'.match(/^(.*?)foo/)[1]; // will return "hello "
It mean that will work on str variable and get the first (and unique) number-group existent. The [0] instead [1] mean that will get all matched code.
Bye :)

replaceAll in javascript and dollar sign

I have a string with 3 dollar signs e.g. $$$Test123. I would like to display this string in a div.
The problem is that when I use replace I get $$Test123 - 2 dollar signs instead of 3.
example:
var sHtml="<_content_>";
var s="$$$Test";
sHtml= sHtml.replace("<_content_>", s);
Now the result of sHtml is $$Test;
Any idea how can it be solved?
javascript does not have a default replace all function. You can write your own like this
function replaceAll(txt, replace, with_this) {
return txt.replace(new RegExp(replace, 'g'),with_this);
}
$ has a special meaning when included in a string for the second argument of a call to replace(). Normally, you would use it to refer to matched expressions within the original string. For example:
"foo foooo".replace(/fo+/g, "$&bar");
//-> "foobar foooobar"
In the example above, $& refers back to the entire match, which is foo in the first word and foooo in the second.
Your problem stems from the special meaning of $. In order to use a literal $ in the match, you must chain two together so that the first escapes the second. To have 3 literal $ symbols, you must chain 6 together, like so:
var sHtml="<_content_>";
var s="$$$$$$Test";
sHtml= sHtml.replace("<_content_>", s);
//-> "$$$Test"
Quotes are your friend
var sHtml="<_content_>"
var s="$$$Test";
sHtml= sHtml.replace("<_content_>", s);
Try this replaceAll function:
http://www.dumpsite.com/replaceAll.php
It performs a replace all using the javascript replace function via a regular expression for speed, and at the same time eliminates the side effects that occur when regular expression special characters are inadvertently present in either the search or replace string.
Using this function you do not have to worry about escaping special characters. All special characters are pre escaped before the replaceAll is preformed.
This function will produce the output you are expecting.
Try it out and provide your feeback.

Regex matches in Javascript nesting issue

First of all, pardon my hacky code, I'm just trying to try this out and I'm learning javascript for the first time. Basically, Given the string "abc!random{3}" would mean return a string that starts with "abc" and ends with a random number from 0-3.
Here is what I have:
var pattern=/!random{([^{]*?)}/gi;
var text="abc!random{3}def!random{4}ghi!random{!random{3}}";
while (pattern.test(text))
{
text=text.replace(pattern, Math.random() * parseInt("$1"));
}
The problem is the parseInt function. It seems like the $1 does not get passed to it..the value of it gets cleared or something. If I do:
text=text.replace(pattern, "$1");
It correctly returns what is in between the { }, so the regex is working and the match is being stored in $1. However, as soon as I use it as a parameter to $1, it seems like the value of it is cleared. What gives?
The second parameter to replace can either be a string to replace the entire match, within which, if present, all occurances of $1, $2, etc. are replaced with the captures OR it can be a function that takes two parameters (the match and the capture) and returns a replacement string for the capture:
var pattern=/!random{([^{]*?)}/gi;
var text="abc!random{3}def!random{4}ghi!random{!random{3}}";
text=text.replace(pattern,
function(match,capture)
{
return Math.random() * parseInt(capture)
});
WScript.echo(text);
Notice that the while loop is unnecessary: the regular expression already has the global flag set ("g"), which says to process the regex globally.
Also note that the function actually receives multiple (m) arguments: 1=the matched string, 2..m=the captures from left to right, m+2=the offset within the string where the match occured, and m+3=the entire string being matched. JavaScript allows the right-most arguments (of any function) to be omitted, which is why the example has only two.
The replace method is operating on the value that it's passed. That is, if it gets a string containing $0, $1, etc., then it replaces that with the correct match. However, what you wrote is first parsing the string "$1" as an integer, multiplying it by a random number, and then passing that as the replacement. So it's almost certainly passing it NaN (due to being unable to parse "$1"), which is not what you want.
So, instead of
text = text.replace(pattern, Math.random() * parseInt("$1"));
I would try
var matches = text.match(pattern);
text = text.replace(pattern, Math.random() * parseInt(matches[1]));

Categories

Resources