Javascript match() string letters which are indicated on regular expression of match - javascript

I have a variable which contain a string and I want to return only the letters from regular expression (“b” and “D”) or any letter that I indicate on regular expression from match().
var kk = "AaBbCcDd".match(/b|D/g);
kk.forEach(function(value,index){
console.log(value,index)
});
My problem is that regular expression I think because is returning b and D but the index is not the index from kk variable and I'm not really sure, why ... so if someone can help me a little bit because I stuck

The match method from javascript only returns an array with the given match:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/match
You would need to implement a new function which will loop through all characters of your string and return the given index of the matches.
This method could use the function search from String.prototype: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/search

You have to write a new function to get the index of the matched regex like a sample below:-
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
alert("match found at " + match.index);
}
Hope this will help you

Actually this is the answer :
var kk = "AaBbCcDd".match(/B?d?/g);
kk.forEach(function(value,index){
console.log(value,index)
});
if someone will encounter this scenario ...
The match() regular expresion B?d? will return an array indicating the position of "B" and "d" of the initial array kk.

Related

I need help getting the first n characters of a string up to when a number character starts

I'm working with a string where I need to extract the first n characters up to where numbers begin. What would be the best way to do this as sometimes the string starts with a number: 7EUSA8889er898 I would need to extract 7EUSA But other string examples would be SWFX74849948, I would need to extract SWFX from that string.
Not sure how to do this with regex my limited knowledge is blocking me at this point:
^(\w{4}) that just gets me the first four characters but I don't really have a stopping point as sometimes the string could be somelongstring292894830982 which would require me to get somelongstring
Using \w will match a word character which includes characters and digits and an underscore.
You could match an optional digit [0-9]? from the start of the string ^and then match 1+ times A-Za-z
^[0-9]?[A-Za-z]+
Regex demo
const regex = /^[0-9]?[A-Za-z]+/;
[
"7EUSA8889er898",
"somelongstring292894830982",
"SWFX74849948"
].forEach(s => console.log(s.match(regex)[0]));
Can use this regex code:
(^\d+?[a-zA-Z]+)|(^\d+|[a-zA-Z]+)
I try with exmaple and good worked:
1- somelongstring292894830982 -> somelongstring
2- 7sdfsdf5456 -> 7sdfsdf
3- 875werwer54556 -> 875werwer
If you want to create function where the RegExp is parametrized by n parameter, this would be
function getStr(str,n) {
var pattern = "\\d?\\w{0,"+n+"}";
var reg = new RegExp(pattern);
var result = reg.exec(str);
if(result[0]) return result[0].substr(0,n);
}
There are answers to this but here is another way to do it.
var string1 = '7EUSA8889er898';
var string2 = 'SWFX74849948';
var Extract = function (args) {
var C = args.split(''); // Split string in array
var NI = []; // Store indexes of all numbers
// Loop through list -> if char is a number add its index
C.map(function (I) { return /^\d+$/.test(I) === true ? NI.push(C.indexOf(I)) : ''; });
// Get the items between the first and second occurence of a number
return C.slice(NI[0] === 0 ? NI[0] + 1 : 0, NI[1]).join('');
};
console.log(Extract(string1));
console.log(Extract(string2));
Output
EUSA
SWFX7
Since it's hard to tell what you are trying to match, I'd go with a general regex
^\d?\D+(?=\d)

Replace multiple strings containing $ sign

I face a problem with regex and string replace and I would love a little bit of help.
I have a string with the following format
<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>
and I need to replace all the $(unique-result) with a string of mine.
I tried the following code but I can't seem to find out why this doesn't work
string.replace(new RegExp('\\$(unique-result)', 'g'), changeString)
The result is the exact same string I gave as an input.
Could anyone help me out but also point out why it didn't work?
Thank you in advance.
You missed escaping. you need to escape properly
let str = `<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>`
let op = str.replace(new RegExp('\\$\\(unique-result\\)','g'), 'Changed')
console.log(op)
In case i am not using any variable i prefer using regex literal (//)
let str = `<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>`
let op = str.replace(/\$\(unique-result\)/g, 'Changed')
console.log(op)
There is more general solution.
First of all, as I mentioned in comments, you don't need to use the RegExp constructor, you can simply pass your regexp between slashes and use flags after last slash:
str.replace(/\$\(unique-result\)/g, "someValue")
The second moment is that String.prototype.replace can accept a function as a second parameter. This will be helpful when there is a lot of named templates in you string. For example, you have the next incoming string:
var incomingString = "$(first-value) says $(second-value) when there is $(third-value)"
With code that you've provided you should call replace 3 times. But if you will use a function as a second parameter, this can be simplified to:
var incomingString = "$(first-value) says $(second-value) when there is $(third-value)"
var data = {
"first-value": "Kappa",
"second-value": "Hey!",
"third-value": "GreyFaceNoSpace"
}
var resultString = incomingString.replace(/\$\(([^)]+)\)/g, (match, capture) => {
console.log(match, capture)
return data[capture]
})
console.log(resultString)
"WHAT IS GOING ON HERE?!" you will probably ask. Nothing complex.
Function that is passed as argument accepts one or more arguments: first is a full match and the others are captured groups. It should return the string, that should replace the full match.
In our regular expression we described that we want to match all possible substrings in format \$\(([^)]+)\), where [^)]+ refers to one-or-more-of-any-symbols-except-a-closing-bracket, and this construction should be captured (it is between not-sanitized brackets).
So, once this regexp will match, it will pass the whole $(...) construction into match argument of passed function, and the name of the template into capture argument. So capture is our key for some data storage and we just returning this value in the function.
That's it! Hope, this will be helpful :)
You can use a simple function to make the substitution. Match every $(string) and apply a function to replace it with a variable stored in an object. Easy and extensible.
const tpl = '<div class="$(unique-result) single-result data-index=$(i)"><div class="airport-data data-index=$(i)">$(name)<br>$(city) ,$(country)</div><div class="airport-code data-index=$(i)">$(IATA)</div></div>';
const vars = {
i : 9,
'unique-result' : 'uniq',
country : 'gb',
city : 'Manchester',
IATA : 'MCH'
};
const replaceVars = (tpl,vars) => {
const replacer = (m, m1) =>
typeof vars[m1] != 'undefined' ? vars[m1] : '';
return tpl.replace(/\$\(([\w-]+)\)/g, replacer);
};
console.log(replaceVars(tpl,vars));

Javascript RegExp match & Multiple backreferences

I'm having trouble trying to use multiple back references in a javascript match so far I've got: -
function newIlluminate() {
var string = "the time is a quarter to two";
var param = "time";
var re = new RegExp("(" + param + ")", "i");
var test = new RegExp("(time)(quarter)(the)", "i");
var matches = string.match(test);
$("#debug").text(matches[1]);
}
newIlluminate();
#Debug when matching the Regex 're' prints 'time' which is the value of param.
I've seen match examples where multiple back references are used by wrapping the match in parenthesis however my match for (time)(quarter)... is returning null.
Where am I going wrong? Any help would be greatly appreciated!
Your regex is literally looking for timequarterthe and splitting the match (if it finds one) into the three backreferences.
I think you mean this:
var test = /time|quarter|the/ig;
Your regex test simply doesn't match the string (as it does not contain the substring timequarterthe). I guess you want alternation:
var test = /time|quarter|the/ig; // does not even need a capturing group
var matches = string.match(test);
$("#debug").text(matches!=null ? matches.join(", ") : "did not match");

Building a Javascript Regex from string

I'm trying to return the number of times a letter appears in a word.
I'm passing the letter to a function like so
function getCount(letter)
{
var pattern = '/' + letter + '/g';
var matches = word.match(pattern);
return matches.length;
}
Unfortunately matches is null so I'm unable to call length on it, I know the letter appears in the word as I've already checked that
word.indexOf(letter) > -1
I suspect the problem is with the way I'm building or evaluating pattern
Here's how you build a non literal regular expression :
var pattern = new RegExp(letter, 'g');
See the MDN on building a regular expression.
And here's a simpler solution to count the occurrences of the letter :
return word.split(letter).length-1;
You can do this:
function hasClass(letter) {
var pattern = new RegExp(letter,'g'); // Create a regular expression from the string
var matches = word.match(pattern);
return matches;
Ref: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp
This was also answered here: javascript new regexp from string

How to know if JavaScript string.replace() did anything?

The replace function returns the new string with the replaces, but if there weren't any words to replace, then the original string is returned. Is there a way to know whether it actually replaced anything apart from comparing the result with the original string?
A simple option is to check for matches before you replace:
var regex = /i/g;
var newStr = str;
var replaced = str.search(regex) >= 0;
if(replaced){
newStr = newStr.replace(regex, '!');
}
If you don't want that either, you can abuse the replace callback to achieve that in a single pass:
var replaced = false;
var newStr = str.replace(/i/g, function(token){replaced = true; return '!';});
As a workaround you can implement your own callback function that will set a flag and do the replacement. The replacement argument of replace can accept functions.
Comparing the before and after strings is the easiest way to check if it did anything, there's no intrinsic support in String.replace().
[contrived example of how '==' might fail deleted because it was wrong]
Javascript replace is defected by design. Why? It has no compatibility with string replacement in callback.
For example:
"ab".replace(/(a)(b)/, "$1$2")
> "ab"
We want to verify that replace is done in single pass. I was imagine something like:
"ab".replace(/(a)(b)/, "$1$2", function replacing() { console.log('ok'); })
> "ab"
Real variant:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
return "$1$2";
})
> ok
> "$1$2"
But function replacing is designed to receive $0, $1, $2, offset, string and we have to fight with replacement "$1$2". The solution is:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
// arguments are $0, $1, ..., offset, string
return Array.from(arguments).slice(1, -2)
.reduce(function (pattern, match, index) {
// '$1' from strings like '$11 $12' shouldn't be replaced.
return pattern.replace(
new RegExp("\\$" + (index + 1) + "(?=[^\\d]|$)", "g"),
match
);
}, "$1$2");
});
> ok
> "ab"
This solution is not perfect. String replacement itself has its own WATs. For example:
"a".replace(/(a)/, "$01")
> "a"
"a".replace(/(a)/, "$001")
> "$001"
If you want to care about compatibility you have to read spec and implement all its craziness.
If your replace has a different length from the searched text, you can check the length of the string before and after. I know, this is a partial response, valid only on a subset of the problem.
OR
You can do a search. If the search is successfull you do a replace on the substring starting with the found index and then recompose the string. This could be slower because you are generating 3 strings instead of 2.
var test = "Hellllo";
var index = test.search(/ll/);
if (index >= 0) {
test = test.substr(0, index - 1) + test.substr(index).replace(/ll/g, "tt");
}
alert(test);
While this will require multiple operations, using .test() may suffice:
const regex = /foo/;
const yourString = 'foo bar';
if (regex.test(yourString)) {
console.log('yourString contains regex');
// Go ahead and do whatever else you'd like.
}
The test() method executes a search for a match between a regular expression and a specified string. Returns true or false.
With indexOf you can check wether a string contains another string.
Seems like you might want to use that.
have a look at string.match() or string.search()
After doing any RegExp method, read RegExp.lastMatch property:
/^$/.test(''); //Clear RegExp.lastMatch first, Its value will be ''
'abcd'.replace(/bc/,'12');
if(RegExp.lastMatch !== '')
console.log('has been replaced');
else
console.log('not replaced');

Categories