Whole word match in JavaScript in an Array - javascript

I've looked high and low for this, with no real idea how to do it now... my scenario:
var strArray = ['Email Address'];
function searchStringInArray(str, strArray) {
for (var j = 0; j < strArray.length; j++) {
if (strArray[j].match(str)) return j;
}
return -1;
}
var match = searchStringInArray('Email', strArray);
Email does NOT equal Email Address... however .match() seems to match the two up, when it shouldn't. I want it to match the exact string. Anyone have any idea how I do this?

You already have .indexOf() for the same thing you are trying to do.
So rather than looping over, why not use:
var match = strArray.indexOf('Email');

String.match is treating your parameter 'Email' as if it is a regular expression. Just use == instead:
if (strArray[j] == str) return j;
From the Mozilla Development Network page on String.match:
If a non-RegExp object obj is passed, it is implicitly converted to a
RegExp by using new RegExp(obj)

Alternatively using RegExp
Use ^ and $
var str = "Email";
new RegExp(str).test("Email address")
Result: true
And for this:
var str = "Email";
new RegExp("^" + str + "$").test("Email address")
Result: false

Related

How can I dynamically use string.replace?

wordsArray = ['guy', 'like', 'sweet', 'potatoes']; //so on and so forth
string = "I am a **NOUN** and I **VERB** **ADJECTIVE** **NOUN**.";
DELIMITER = "**";
for (var i = 0; i < wordsArray.length; i++)
{
string.replace(DELIMITER, wordsArray[i]);
}
Hi, this is a simplified version of my code. I'm creating a mad lib, and the length of wordsArray will always be equal to the number of fill in the blanks. The problem with my current code is that in the for loop, it will replace every **. The thing is, I want to replace the entire thing, like **NOUN**, not just **. But since whatever is in between ** ** won't always be the same, string.replace() won't exactly work. Can Anyone suggest me an edit that could replace all the part of speeches but still eventually return string as a, well, block of proper text?
You can do it using string.match by catching all those **<STRINGS>** first:
var wordsArray = ['guy', 'like', 'sweet', 'potatoes'];
var string = "I am a **NOUN** and I **VERB-** **ADJECTIVE** **NOUN**.";
var DELIMITER = "**";
var newString = string; // copy the string
var stringArray = string.match(/(\*\*[A-Za-z-]+\*\*)/g); // array of all **<STRINGS>**
for (var i = 0; i < wordsArray.length; i++) {
newString = newString.replace(stringArray[i], wordsArray[i]);
}
console.log(newString);
You can bind your array to the replacer and call replace on your string once, I think it is much simpler:
"I am a **NOUN** and I **VERB** **ADJECTIVE** **NOUN**.".replace(/(\*\*\w+\*\*)/gi,(function(){
this._currentIndex = this._currentIndex || 0;
return this[this._currentIndex++];
}).bind(['guy', 'like', 'sweet', 'potatoes']));
//"I am a guy and I like sweet potatoes."
Using reduce:
const string = "I am a **NOUN** and I **VERB** **ADJECTIVE** **NOUN**.";
const newString = ['guy', 'like', 'sweet', 'potatoes'].reduce(
(theString, replacement) => theString.replace(/\*{2}\w+\*{2}/, replacement),
string
)

Regex doesn't seem to work properly in my code

What I am trying to do is turn, for example "{{John}}" into "John".
First I am parsing from a string:
var parametrar = content.match(/[{{]+[Aa-Åå]+[}}]/g);
Here regex works fine and it parses as it should. I need to parse the "{}" to find stuff in the string.
But then I'm trying to parse out the "{}" from each "parametrar":
for (var i = 0; i < parametrar.length; i++) {
parametrar = parametrar[i].replace(/[{}]/g, "");
}
When I alert "parametrar" all I get is one "a". I have no idea what I'm doing wrong here, seems it should work.
Try to add greedy matching to maque's answer with using question mark(?).
"{{John}}".replace(/\{\{(.*?)\}\}/g,"$1");
It extracts "John" properly from "{{John}} and Martin}}" input. Otherwise it matches to "John}} and Martin".
You can match the name with braces around and then just use the first capturing group (m[1]):
var re = /\{{2}([a-zA-ZÅå]+)\}{2}/g;
var str = '{{John}}';
if ((m = re.exec(str)) !== null) {
paramterar = m[1];
alert(paramterar);
}
If you have a larger string that contains multiple {{NAME}}s, you can use the code I suggested in my comment:
var re = /\{{2}([a-zA-ZÅå]+)\}{2}/g;
var str = 'My name is {{John}} and {{Vasya}}.';
var arr = [];
while ((m = re.exec(str)) !== null) {
paramterar = m[1];
arr.push(m[1]);
}
alert(arr);
alert(str.replace(/([a-zA-ZÅå])\}{2}/g,"$1").replace(/\{{2}(?=[a-zA-ZÅå])/g, ""))
I have also fixed the character class to only accept English letters + Å and å (revert if it is not the case, but note that [Aa-Åå] is not matching any upper case Englihs letters from B to Z, and matches characters like §.) Please check the ANSI table to see what range you need.
Just do it like that:
"{{John}}".replace(/\{\{(.*)\}\}/g,"$1");
So you are searching for string that have double '{' (these needs to be escaped), then there is something (.*) then again '}' and your output is first match of the block.
Try this:
var parametrar = content.replace(/\{\{([a-åA-Å]+)\}\}/g, "$1");
This gives you a "purified" string. If you want an array, than you can do this:
var parametrar = content.match(/\{\{[a-åA-Å]+\}\}/g);
for (var i = 0, len = parametrar.length; i < len; i++) {
parametrar = parametrar[i].replace(/\{\{([a-åA-Å]+)\}\}/g, "$1");
}

Using regular expression to split a string

I have a string which I need to separate correctly:
self.view.frame.size.height = 44
I need to get only view, frame, size, and height. And I need to do it with a regular expression.
So far I've tried a lot of variants, none of them are even close to what I want to get. And my code now looks like this:
var testString = 'self.view.frame.size.height = 44'
var re = new RegExp('\\.(.*)\\.', "g")
var array = re.exec(testString);
console.log('Array length is ' + array.length)
for (var i = 0; i < array.length; i++) {
console.log('<' + array[i] + ">");
}
And it doesn't work at all:
Array length is 2
<.view.frame.size.>
<view.frame.size>
I'm new at Javascript, so maybe I want the impossible, let me know.
Thanks.
In Javascript, executing a regexp with the g modifier doesn't return all the matches at once. You have to execute it repeatedly on the same input string, and each one returns the next match.
You also need to change the regexp so it only returns one word at a time. .* is greedy, so it returns the longest possible match, so it was returning all the words between the first and last .. [^.]* will match a sequence of non-dot characters, so it will just return one word. You can't include the second . in the regexp, because that will interfere with the repetition -- each repetition starts searching after the end of the previous match, and there's no beginning . after the ending . of the word. Also, there's no . after height, so the last word won't match it.
EDIT: I've changed the regexp to use \w* instead of [^.]*, because it was grabbing the whole height = 44 string instead of just height.
var testString = 'self.view.frame.size.height = 44';
var re = /\.(\w*)/g;
var array = [];
var result;
while (result = re.exec(testString)) {
array.push(result[1]);
}
console.log('Array length is ' + array.length)
for (var i = 0; i < array.length; i++) {
console.log('<' + array[i] + ">");
}
If you're sure that your data will be always in the same format you can use this:
function parse (string) {
return string.split(" = ").shift().split(".").splice(1);
}
In your context, split is a MUCH better option:
var str = "self.view.frame.size.height = 44";
var bits1 = str.split(" ")[0];
var bits2 = bits1.split(".");
bits2.shift(); // get rid of the unwanted self
console.log(bits2);

Javascript split at multiple delimters while keeping delimiters

Is there a better way than what I have (through regex, for instance) to turn
"div#container.blue"
into this
["div", "#container", ".blue"];
Here's what I've have...
var arr = [];
function process(h1, h2) {
var first = h1.split("#");
arr.push(first[0]);
var secondarr = first[1].split(".");
secondarr[0] = "#" + secondarr[0];
arr.push(secondarr[0]);
for (i = 1; i< secondarr.length; i++) {
arr.push(secondarr[i] = "." + secondarr[i]);
}
return arr;
}
Why not something like this?
'div#container.blue'.split(/(?=[#.])/);
Because it's simply looking for a place where the next character is either # or the literal ., this does not capture anything, which makes it a zero length match. Because it's zero-length match, nothing is removed.
As you've probably found, the issue is that split removes the item you're splitting on. You can solve that with regex capturing groups (the parenthesis):
var result = 'div#container.blue'.split(/(#[^#|^.]*)|(\.[^#|^.]*)/);
Now we've got the issue that result contains a lot of falsy values you don't want. A quick filter fixes that:
var result = 'div#container.blue'.split(/(#[^#|^.]*)|(\.[^#|^.]*)/).filter(function(x) {
return !!x;
});
Appendix A: What the heck is that regex
I'm assuming you're only concerned with # and . as characters. That still gives us this monster: /(#[^#|^.]*)|(\.[^#|^.]*)/
This means we'll capture either a # or ., and then all the characters up until the next # or . (remembering that a period is significant in regex, so we need to escape it, unless we're inside the brackets).
I've written an extensions of the Script type for you. It allows you to choose which delimiters to use, passing them in a string:
String.prototype.splitEx = function(delimiters) {
var parts = [];
var current = '';
for (var i = 0; i < this.length; i++) {
if (delimiters.indexOf(this[i]) < 0) current += this[i];
else {
parts.push(current);
current = this[i];
}
}
parts.push(current);
return parts;
};
var text = 'div#container.blue';
console.log(text.splitEx('#.'));

need a regular expression to search a matching last name

I have a javascript array which holds strings of last names.
I need to loop this array and separate out the last names which match a given string.
var names = ['woods','smith','smike'];
var test = 'smi';
var c = 0;
var result = new Array();
for(var i = 0; i < names.length; i++)
{
if(names[i].match(test))// need regular expression for this
result[c++] = names[i];
}
return result;
name should match the test string even if the test lies within the name. so... mik should match 'Mike' and 'Smike' also.
Any help is really appreciated!
You can create a regex from a string:
var nameRe = new RegExp("mik", "i");
if(names[i].match(nameRe))
{
result.push(names[i]);
}
Make sure to escape regex meta-characters though - if your string may contain them. For example ^, $ may result in a miss-match, and *, ? ) and more may result in an invalid regex.
More info: regular-expressions.info/javascript
You can do this without regex:
if (names[i].toLowerCase().indexOf(test.toLowerCase()) >= 0)
// ...
Javascript string .search is what you're looking for.. You don't even need regex although search supports that too.
var names = ['woods','smith','smike'];
var test = 'smi';
var c = 0;
var result = new Array();
for(var i = 0; i < names.length; i++)
{
if(names[i].toLowerCase().search(test))// need regular expression for this
result.push(names[i]);
}
return result;
You can do this with one regex.
var r = new RegExp(names.join('|'), "igm");
'woods smith'.match(r);
You don't need regex for this, so I'd recommend using string manipulation instead. It's almost (almost!) always better to use string functions instead of regex when you can: They're usually faster, and it's harder to make a mistake.
for(var i = 0; i < names.length; i++)
{
if(names[i].indexOf(test) > -1)
//match, do something with names[i]...
}

Categories