I'm trying to retrieve every matching word from array but .match retuns an undefined function. I'm pretty sure I don't need to convert anything because I'm comparing two strings:
var hashtags = [ '#hr', '#acc', '#sales' ];
var message = "hello there #hr #acc";
var filteredMessage = _.filter( message.split( ' ' ), value => value.match( hashtags ) );
// suppose to return [ '#hr', '#acc' ]
You're using match() incorrectly. This function accepts a regular expression as a parameter and you're using it with an array.
You can achieve what you want by checking if the value is one of the array's elements.
Here is an example:
var hashtags = [ '#hr', '#acc', '#sales' ];
var message = "hello there #hr #acc";
var filteredMessage = _.filter( message.split( ' ' ), value => hashtags.indexOf(value) != -1 );
console.log(filteredMessage);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
The problem with what you are trying to do is hashtags are an array and match takes in a regular expression, so I don't think it is the method you want to use.
An alternative solution is to use the intersection function provided by lodash
_.intersection(hashtags, message.split(' '))
If you do want to use regular expressions (and match) I think you probably have to loop over both arrays to get an intersection.
Below works for me
var filteredMessage = message.split(' ').filter(word => hashtags.includes(word));
Since you are using underscore already:
filteredMessage = _.filter( message.split( ' ' ), value => _.find(hashtags, tag => tag === value))
Related
I am trying to create a regular expression to separate each word from . (dot) in JavaScript.
function myFunction() {
var url = "in.k1.k2.k3.k4.com"
var result
var match
if (match = url.match(/^[^\.]+\.(.+\..+)$/)) {
console.log(match);
}
}
Actual result is:
match[0] : in.k1.k2.k3.k4.com
match[1] : k1.k2.k3.k4.com
Expected result is:
match[0] : in.k1.k2.k3.k4.com
match[1] : k1.k2.k3.k4.com
match[2] : k2.k3.k4.com
match[3] : k3.k4.com
match[4] : k4.com
Please help me to create perfect regular expression.
Using a regex, in this case, might not be the best choice. You could simply split your string at the . and then join them when you need it.
function recursivelySplitText(arrayOfString, output) {
// check if the output is set, otherwise create it.
if(!output) {
output = [];
}
// we add the current value to the output
output.push(arrayOfString.join('.'));
// we remove the first element of the array
arrayOfString.splice(0, 1);
// if we just have one element left in the array ( com ) we return the array
// otherwise, we call the function again with the newly splitted array.
return arrayOfString.length === 1 ? output : recursivelySplitText(arrayOfString, output);
}
const text = 'in.k1.k2.k3.k4.com';
// we need to split it first to have an array of string rather than a string.
console.log(recursivelySplitText(text.split('.')));
Here i used recursion because it is fun, but it is not the only way of getting the same result.
Instead of a regex you could use a combination of split() and map() to create the output array you require. Try this:
function myFunction() {
var arr = "in.k1.k2.k3.k4.com".split('.');
var output = arr.map((v, i) => arr.slice(i).join('.'));
console.log(output);
}
myFunction();
I have a string which is composed of terms separated by slashes ('/'), for example:
ab/c/def
I want to find all the prefixes of this string up to an occurrence of a slash or end of string, i.e. for the above example I expect to get:
ab
ab/c
ab/c/def
I've tried a regex like this: /^(.*)[\/$]/, but it returns a single match - ab/c/ with the parenthesized result ab/c, accordingly.
EDIT :
I know this can be done quite easily using split, I am looking specifically for a solution using RegExp.
NO, you can't do that with a pure regex.
Why? Because you need substrings starting at one and the same location in the string, while regex matches non-overlapping chunks of text and then advances its index to search for another match.
OK, what about capturing groups? They are only helpful if you know how many /-separated chunks you have in the input string. You could then use
var s = 'ab/c/def'; // There are exact 3 parts
console.log(/^(([^\/]+)\/[^\/]+)\/[^\/]+$/.exec(s));
// => [ "ab/c/def", "ab/c", "ab" ]
However, it is unlikely you know that many details about your input string.
You may use the following code rather than a regex:
var s = 'ab/c/def';
var chunks = s.split('/');
var res = [];
for(var i=0;i<chunks.length;i++) {
res.length > 0 ? res.push(chunks.slice(0,i).join('/')+'/'+chunks[i]) : res.push(chunks[i]);
}
console.log(res);
First, you can split the string with /. Then, iterate through the elements and build the res array.
I do not think a regular expression is what you are after. A simple split and loop over the array can give you the result.
var str = "ab/c/def";
var result = str.split("/").reduce(function(a,s,i){
var last = a[i-1] ? a[i-1] + "/" : "";
a.push(last + s);
return a;
}, []);
console.log(result);
or another way
var str = "ab/c/def",
result = [],
parts=str.split("/");
while(parts.length){
console.log(parts);
result.unshift(parts.join("/"));
parts.pop();
}
console.log(result);
Plenty of other ways to do it.
You can't do it with a RegEx in javascript but you can split parts and join them respectively together:
var array = "ab/c/def".split('/'), newArray = [], key = 0;
while (value = array[key++]) {
newArray.push(key == 1 ? value : newArray[newArray.length - 1] + "/" + value)
}
console.log(newArray);
May be like this
var str = "ab/c/def",
result = str.match(/.+?(?=\/|$)/g)
.map((e,i,a) => a[i-1] ? a[i] = a[i-1] + e : e);
console.log(result);
Couldn't you just split the string on the separator character?
var result = 'ab/c/def'.split(/\//g);
disclaimer - absolutely new to regexes....
I have a string like this:
subject=something||x-access-token=something
For this I need to extract two values. Subject and x-access-token.
As a starting point, I wanted to collect two strings: subject= and x-access-token=. For this here is what I did:
/[a-z,-]+=/g.exec(mystring)
It returns only one element subject=. I expected both of them. Where i am doing wrong?
The g modifier does not affect exec, because exec only returns the first match by specification. What you want is the match method:
mystring.match(/[a-z,-]+=/g)
No regex necessary. Write a tiny parser, it's easy.
function parseValues(str) {
var result = {};
str.split("||").forEach(function (item) {
var parts = item.split("=");
result[ parts[0] /* key */ ] = parts[1]; /* value */
});
return result;
}
usage
var obj = parseValues("subject=something||x-access-token=something-else");
// -> {subject: "something", x-access-token: "something-else"}
var subj = obj.subject;
// -> "something"
var token = obj["x-access-token"];
// -> "something-else"
Additional complications my arise when there is an escaping schema involved that allows you to have || inside a value, or when a value can contain an =.
You will hit these complications with regex approach as well, but with a parser-based approach they will be much easier to solve.
You have to execute exec twice to get 2 extracted strings.
According to MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
If your regular expression uses the "g" flag, you can use the exec() method multiple times to find successive matches in the same string.
Usually, people extract all strings matching the pattern one by one with a while loop. Please execute following code in browser console to see how it works.
var regex = /[a-z,-]+=/g;
var string = "subject=something||x-access-token=something";
while(matched = regex.exec(string)) console.log(matched);
You can convert the string into a valid JSON string, then parse it to retrieve an object containing the expected data.
var str = 'subject=something||x-access-token=something';
var obj = JSON.parse('{"' + str.replace(/=/g, '":"').replace(/\|\|/g, '","') + '"}');
console.log(obj);
I don't think you need regexp here, just use the javascript builtin function "split".
var s = "subject=something1||x-access-token=something2";
var r = s.split('||'); // r now is an array: ["subject=something1", "x-access-token=something2"]
var i;
for(i=0; i<r.length; i++){
// for each array's item, split again
r[i] = r[i].split('=');
}
At the end you have a matrix like the following:
y x 0 1
0 subject something1
1 x-access-token something2
And you can access the elements using x and y:
"subject" == r[0][0]
"x-access-token" == r[1][0]
"something2" == r[1][1]
If you really want to do it with a pure regexp:
var input = 'subject=something1||x-access-token=something2'
var m = /subject=(.*)\|\|x-access-token=(.*)/.exec(input)
var subject = m[1]
var xAccessToken = m[2]
console.log(subject);
console.log(xAccessToken);
However, it would probably be cleaner to split it instead:
console.log('subject=something||x-access-token=something'
.split(/\|\|/)
.map(function(a) {
a = a.split(/=/);
return { key: a[0], val: a[1] }
}));
I have a string that looks like this:
{{tagName(21, 'hello, jane','smith')}}
I'm trying to use regex to match() this string to result in:
[0] = tagName
[1] = 21
[2] = 'hello, jane'
[3] = 'smith'
The parameter part of the string can grow. That is to say, it may have more or less parameters and the regex needs to be "greedy" yet knows how to group them up.
I've been trying something like that: ^\{\{([^\(]+)\({1}(.*)\){1}\}\}
But this results in:
[0] = tagName
[1] = 21, 'hello, jane','smith'
What should I do to my regex to get the results I want?
Replace {, }, (, ) with empty string; match [a-z]+, \d+, '.+' followed by , or end of input
var str = "{{tagName(21, 'hello, jane','smith')}}";
var res = str.replace(/\{|\}|\(|\)/g, "")
.match(/([a-z]+)|\d+|('.+')(?=,)|('.+')(?=$)/ig);
console.log(res);
If you're ok with using two regexes, you can return a new array with function name and concat all the parameters onto that array.
With ES6 you can use the spread operator:
const str = "{{tagName(21, 'hello, jane','smith')}}";
const result = str.match(/^\{\{([^\(]+)\({1}(.*)\){1}\}\}/);
console.log([
result[1],
...result[2].match(/^\d+|'.*?'/g)
])
In ES5 you'll have to concat the parameters onto the array containing the function name as its first item:
var str = "{{tagName(21, 'hello, jane','smith')}}";
var result = str.match(/^\{\{([^\(]+)\({1}(.*)\){1}\}\}/);
console.log([result[1]].concat(result[2].match(/^\d+|'.*?'/g)))
In reality, you could concat in ES6, but
So far I've manage to come up with the following:
([A-Za-z]+)|('.*?'|[^',\s\(]+)(?=\s*,|\s*\))
Tested on https://regex101.com
I have a string in which every value is between [] and it has a . at the end. How can I separate all values from the string?
This is the example string:
[value01][value02 ][value03 ]. [value04 ]
//want something like this
v1 = value01;
v2 = value02;
v3 = value03;
v4 = value04
The number of values is not constant. How can I get all values separately from this string?
Use regular expressions to specify multiple separators. Please check the following posts:
How do I split a string with multiple separators in javascript?
Split a string based on multiple delimiters
var str = "[value01][value02 ][value03 ]. [value04 ]"
var arr = str.split(/[\[\]\.\s]+/);
arr.shift(); arr.pop(); //discard the first and last "" elements
console.log( arr ); //output: ["value01", "value02", "value03", "value04"]
JS FIDDLE DEMO
How This Works
.split(/[\[\]\.\s]+/) splits the string at points where it finds one or more of the following characters: [] .. Now, since these characters are also found at the beginning and end of the string, .shift() discards the first element, and .pop() discards the last element, both of which are empty strings. However, your may want to use .filter() and your can replace lines 2 and 3 with:
var arr = str.split(/[\[\]\.\s]+/).filter(function(elem) { return elem.length > 0; });
Now you can use jQuery/JS to iterate through the values:
$.each( arr, function(i,v) {
console.log( v ); // outputs the i'th value;
});
And arr.length will give you the number of elements you have.
If you want to get the characters between "[" and "]" and the data is regular and always has the pattern:
'[chars][chars]...[chars]'
then you can get the chars using match to get sequences of characters that aren't "[" or "]":
var values = '[value01][value02 ][value03 ][value04 ]'.match(/[^\[\]]+/g)
which returns an array, so values is:
["value01", "value02 ", "value03 ", "value04 "]
Match is very widely supported, so no cross browser issues.
Here's a fiddle: http://jsfiddle.net/5xVLQ/
Regex patern: /(\w)+/ig
Matches all words using \w (alphanumeric combos). Whitespace, brackets, dots, square brackets are all non-matching, so they don't get returned.
What I do is create a object to hold results in key/value pairs such as v1:'value01'. You can iterate through this object, or you can access the values directly using objRes.v1
var str = '[value01][value02 ][value03 ]. [value04 ]';
var myRe = /(\w)+/ig;
var res;
var objRes = {};
var i=1;
while ( ( res = myRe.exec(str) ) != null )
{
objRes['v'+i] = res[0];
i++;
}
console.log(objRes);