I have a string like this:
20 EQUALS 'Value goes here'
I want to split it up into 3 separate strings:
conditionField = 20
conditionOperation = 'EQUALS'
conditionValue = 'Value goes here'
I tried this to get the Condition Field:
var conditionField = condition.replace(/(.*)(.*EQUALS)/, '$1');
But it get's the beginning and the end.
I'm having trouble splitting it up and dealing with the white space and spaces in the value.
Your question would actually be a bit of challenge if you wanted to arbitrarily extract quoted terms along with individual words. But since you appear to have a rather fixed structure, starting with a single number, then a single word command, followed by a third term, we can use the following regex pattern here:
([^\\s]*)\\s+([^\\s]*)\\s+(.*)
Each term in parentheses above will be made available as a capture group after the match has been run. In this case, I just blanket everything after the first two terms together.
var string = "20 EQUALS 'Value goes here'";
var re = new RegExp("([^\\s]*)\\s+([^\\s]*)\\s+(.*)");
match = re.exec(string);
if (match != null) {
console.log(match[1])
console.log(match[2])
console.log(match[3])
}
Try this :
var data = '20 EQUALS 30';
var a = data.split(/(\d*) ([a-zA-Z]*) (\d*)/g);
conditionField = a[1];
conditionOperation = a[2];
conditionValue = a[3];
Related
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)
I'm working on a template engine, I try to catch all strings inside <% %>, but when I work it on the <%object.property%> pattern, everything fails.
My code:
var render = function(input, data){
var re = /<%([^%>]+)?%>/g;
var templateVarArray;
// var step = "";
while((templateVarArray = re.exec(input))!=null){
var strArray = templateVarArray[1].split(".");
// step+= templateVarArray[1]+" ";
if(strArray.length==1)
input = input.replace(templateVarArray[0], data[templateVarArray[1]]);
if(strArray.length==2){
input = input.replace(templateVarArray[0], data[strArray[0]][strArray[1]]);
}
}
// return step;
return input;
}
var input = "<%test.child%><%more%><%name%><%age%>";
document.write(render(input,{
test: { child: "abc"},
more: "MORE",
name:"ivan",
age: 22
}));
My result:
abc<%more%><%name%>22
what I want is: abc MORE ivan 22
Also, the RegExp /<%([^%>]+)?%>/g is referenced online, I did search its meaning, but still quite not sure the meaning. Especially why does it need "+" and "?", thanks a lot!
If you add a console.log() statement it will show where the next search is going to take place:
while((templateVarArray = re.exec(input))!=null){
console.log(re.lastIndex); // <-- insert this
var strArray = templateVarArray[1].split(".");
// step+= templateVarArray[1]+" ";
if(strArray.length==1)
input = input.replace(templateVarArray[0], data[templateVarArray[1]]);
if(strArray.length==2){
input = input.replace(templateVarArray[0], data[strArray[0]][strArray[1]]);
}
}
You will see something like:
14
26
This means that the next time you run re.exec(...) it will start at index 14 and 26 respectively. Consequently, you miss some of the matches after you substitute data in.
As #Alexander points out take the 'g' off the end of the regex. Now you will see something like this:
0
0
This means the search will start each time from the beginning of the string, and you should now get what you were looking for:
abcMOREivan22
Regarding your questions on the RegEx and what it is doing, let's break the pieces apart:
<% - this matches the literal '<' followed immediately by '%'
([^%>]+) - the brackets (...) indicate we want to capture the portion of the string that matches the expression within the brackets
[^...] - indicates to match anything except what follows the '^'; without the '^' would match whatever pattern is within the []
[^%>] - indicates to match and exclude a single character - either a '%' or '>'
[^%>]+ - '+' indicates to match one or more; in other words match one or more series of characters that is not a '%' and not a '>'
? - this indicates we want to do reluctant matching (without it we do what is called 'greedy' matching)
%> - this matches the literal '%' followed immediately by '>'
The trickiest part to understand is the '?'. Used in this context it means that we stop matching with the shortest pattern that will still match the overall regex. In this case, it doesn't make any difference whether you include it though there are times where it will matter depending on the matching patterns.
Suggested Improvement
The current logic is limited to data that nests two levels deep. To make it so it can handle an arbitrary nesting you could do this:
First, add a small function to do the substitution:
var substitute = function (str, data) {
return str.split('.').reduce(function (res, item) {
return res[item];
}, data);
};
Then, change your while loop to look like this:
while ((templateVarArray = re.exec(input)) != null) {
input = input.replace(templateVarArray[0], substitute(templateVarArray[1], data));
}
Not only does it handle any number of levels, you might find other uses for the 'substitute()' function.
The RegExp.prototype.exec() documentation says:
If your regular expression uses the "g" flag, you can use the exec() method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of str specified by the regular expression's lastIndex property (test() will also advance the lastIndex property).
But you are replacing each match in the original string so next re.exec with a lastIndex already set not to zero will continue to search not from beginning and will omit something.
So if you want to search and substitute found results in original string - just omit \g global key:
var render = function(input, data) {
var re = /<%([^%>]+)?%>/;
var templateVarArray;
// var step = "";
while (!!(templateVarArray = re.exec(input))) {
var strArray = templateVarArray[1].split(".");
if (strArray.length == 1)
input = input.replace(templateVarArray[0], data[templateVarArray[1]]);
if (strArray.length == 2) {
input = input.replace(templateVarArray[0], data[strArray[0]][strArray[1]]);
}
}
// return step;
return input;
}
var input = "<%test.child%><%more%><%name%><%age%>";
document.write(render(input, {
test: {
child: "abc"
},
more: "MORE",
name: "ivan",
age: 22
}));
I have a two different different numbers, each with a dollar sign. I want to get the two numbers separately.
JavaScript:
function price_range(id){
//var str = $('#'+id).val();
var str = '$75 - $300';
var removeDollar = str.replace(/\$/,'');
alert(removeDollar);
}
Click Here
The above code only replaces the first dollar sign, but I have two dollar signs with number. How can I get 75 and 300 separately?
You can just get all the numbers from the string, like this
console.log('$75 - $300'.match(/(\d+)/g));
# [ '75', '300' ]
Note: This simple RegEx will match and get all the numbers, even if there are more than 2 numbers in the string. But for this simple task, you don't need a complicate RegEx.
If you want to fix your program, you can do it like this
console.log('$75 - $300'.replace(/\$/g, '').split(/\s*-\s*/));
# [ '75', '300' ]
replace(/\$/g, '') will replace $ symbol from the string and then you can split the string based on \s*-\s*, which means zero or more white space characters, followed by -, and followed by zero or more white space characters.
You could extend the regular expression in the .replace() function to have a global flag g:
str.replace(/\$/g,'');
The whole script would work like this, but will be specific to removing the $ sign.
function price_range(id){
//var str = $('#'+id).val();
var str = '$75 - $300';
var removeDollar = str.replace(/\$/g,'');
alert(removeDollar);
}
Click Here
An option would be to extract numbers with a regular expression like this:
var str = '$70 - $300 some other 500%';
var arrOfStrings = str.match(/\d+/gi);
// arrOfStrings = ['70', '300', '500']
var arrOfNrs = arrOfStrings.map(function (e) {
return parseInt(e);
}); // map not supported by all browsers. you can use the _.map from underscorejs.org
// arrOfNrs = [70, 300, 500]
I only want to remove the first 100 words and keep whats remaining from the string.
The code I have below does the exact opposite:
var short_description = description.split(' ').slice(0,100).join(' ');
Remove the first argument:
var short_description = description.split(' ').slice(100).join(' ');
Using slice(x, y) will give you elements from x to y, but using slice(x) will give you elements from x to the end of the array. (note: this will return the empty string if the description has less than 100 words.)
Here is some documentation.
You could also use a regex:
var short_description = description.replace(/^([^ ]+ ){100}/, '');
Here is an explanation of the regex:
^ beginning of string
( start a group
[^ ] any character that is not a space
+ one or more times
then a space
) end the group. now the group contains a word and a space.
{100} 100 times
Then replace those 100 words with nothing. (note: if the description is less than 100 words, this regex will just return the description unchanged.)
//hii i am getting result using this function
var inputString = "This is file placed on Desktop"
inputString = removeNWords(inputString, 2)
console.log(inputString);
function removeNWords(input,n) {
var newString = input.replace(/\s+/g,' ').trim();
var x = newString.split(" ")
return x.slice(n,x.length).join(" ")
}
The reason this is doing the opposite, is that slice returns the selected elements (in this case, the first one hundred) and returns them in it's own array. To get all of the elements after one hundred, you would have to do something like description.slice(100) to get the split array properly, and then your own join to merge back the array.
var short_description = description.split(' ').slice(100).join(' ');
I'm trying to split a string into an array based on the second occurrence of the symbol _
var string = "this_is_my_string";
I want to split the string after the second underscore. The string is not always the same but it always has 2 or more underscores in it. I always need it split on the second underscore.
In the example string above I would need it to be split like this.
var split = [this_is, _my_string];
var string = "this_is_my_string";
var firstUnderscore = string.indexOf('_');
var secondUnderscore = string.indexOf('_', firstUnderscore + 1);
var split = [string.substring(0, secondUnderscore),
string.substring(secondUnderscore)];
Paste it into your browser's console to try it out. No need for a jsFiddle.
var string = "this_is_my_string";
var splitChar = string.indexOf('_', string.indexOf('_') + 1);
var result = [string.substring(0, splitChar),
string.substring(splitChar, string.length)];
This should work.
var str = "this_is_my_string";
var matches = str.match(/(.*?_.*?)(_.*)/); // MAGIC HAPPENS HERE
var firstPart = matches[1]; // this_is
var secondPart = matches[2]; // _my_string
This uses regular expressions to find the first two underscores, and captures the part up to it and the part after it. The first subexpression, (.*?_.*?), says "any number of characters, an underscore, and again any number of characters, keeping the number of characters matched as small as possible, and capture it". The second one, (_.*) means "match an underscore, then any number of characters, as much of them as possible, and capture it". The result of the match function is an array starting with the full matched region, followed by the two captured groups.
I know this post is quite old... but couldn't help but notice that no one provided a working solution. Here's one that works:
String str = "this_is_my_string";
String undScore1 = str.split("_")[0];
String undScore2 = str.split("_")[1];
String bothUndScores = undScore1 + "_" + undScore2 + "_";
String allElse = str.split(bothUndScores)[1];
System.out.println(allElse);
This is assuming you know there will always be at least 2 underscores - "allElse" returns everything after the second occurrence.