I have a string like below
Original string : results
1apple23oranges : 1 , 23
4apples1oranges : 4, 1
25oranges : 25
By regular expression or any, i can't figure out how to get the above results as pure digits in javascript.
Any idea pls?
Use the regular expression \d+, which means any digit from 0 to 9 (\d) repeated one or more times (+). The qualifier g will make the search global (ie: don't stop on the first hit).
resultArray = original.match(/\d+/g);
This will result an array with all the numbers, to join them using ", " a separator, use the function join()
resultString = original.match(/\d+/g).join(", ");
'1apple23oranges'.match(/\d+/g);
Use match function on your string object with expression .match(/\d+/g).
Eg. var a = "1apple23oranges"
var res = a.match(/\d+/g)
You can separate each values by comma.
Try "1apple23oranges".match(/(\d+)/g);
Note: If you need the digits as integer value then you have to use parseInt for that. If you are using jQuery then you can have all the integers in an array
var arr = new Array();
$.each("1apple23oranges".match(/(\d+)/g), function(index, value){ arr.push(parseInt(value, 10));});
Related
I have a string which can be of variable length, for this question I will keep it simply and assume a small subset of items in the list.
The objective is to split the string to create multiple string values where the length is greater than 11, however I would need to preserve the comma values (e.g. I can't just split every 11 characters, I must split at the last comma before the 11th character
test1,test2,test3,test4,test5
For arguments sake, lets propose the max length of the string can be 10 characters, so in this example the above would be converted to three separate strings:
test1,test2
test3,test4
test5
To clarify there is a maximum allowed character limit of 11 characters per split value, but we want to use these as efficiently as possible.
You can use ( when you want to treat as 10 as min length and want to continue upto to the next upcoming , or end of string )
(.{10,}?)(?:,|$)
const input = 'test1,test2,test3,test4,test5';
console.log(
input.split(/(.{10,}?)(?:,|$)/g).filter(Boolean)
);
Update:- Since you want the value in between a range you can use this
(.{1,22})(?:,|$)
Demo
I am not sure if you are looking for something like this. But this code gives the output according to your example :
// Try edit msg
var msg = 'test1,test2,test3,test4,test5'
msgs = msg.split(",")
final = []
str = ""
msgs.map( m => {
str += str == "" ? m : "," + m
if (str.length > 10){
final.push(str)
str = ""
}
})
final.push(str)
console.log(final)
OUTPUT:
[
"test1,test2" ,
"test3,test4" ,
"test5"
]
Use a regular expression to match a non-comma, followed by up to 8 characters, followed by another non-comma, and lookahead for either a comma or the end of the string:
const input = 'test1,test2,test3,test4,test5';
console.log(
input.match(/[^,].{0,8}[^,](?=,|$)/g)
);
Because in the given input, test1,test2 (and any other combination of multiple items) will be length 11 or more, they won't be included.
If you want to allow length 11 as well, then change {0,8} to {0,9}:
const input = 'test1,test2,test3,test4,test5';
console.log(
input.match(/[^,].{0,9}[^,](?=,|$)/g)
);
If there might be items of length 1, make everything matched after the first non-comma optional in a non-capturing group:
const input = 'test1,test2,test3,test4,t';
console.log(
input.match(/[^,](?:.{0,9}[^,])?(?=,|$)/g)
);
Given any of the following strings, where operator and value are just placeholders:
"operator1(value)"
"operator1(value), operator2(value)"
"operator1(value), operator2(value), operator_n(value)"
I need to be able to match so i can get each operator and it's value as follows:
[[operator1, value]]
[[operator1, value], [operator2, value]]
[[operator1, value], [operator2, value], [operator_n, value]]
Please Note: There could be n number of operators (comma delimited) in the given string.
My current attempt will match on operator1(value) but nothing with multiple operators. See regex101 for the results.
/^(.*?)\((.*)\)$/
You should be able to do this with a single regex using the global flag.
var re= /(?:,\s*)?([^(]+?)\(([^)]+)\)/g;
var results = re.exec(str);
See the result at Regex 101: https://regex101.com/r/eC3uK3/2
Here's a pure regex answer to this question, this will work so long as your variables are always separated by a , and a space, should traverse through lines without much issue
https://regex101.com/r/eC3uK3/4
([^\(]*)(\([^, ]*\))(?:, )?(?:\n)?
Matches on:
operator1(value), operator2(value), operator_n(value),
operator1(value), operator2(value)
Explanation:
So, this sets up 2 capture groups and 2 non-capture groups.
The first capture group will match a value name until a parenthesis (by using a negated set and greedy). The second capture group will grab the parenthesis and the value name until the end of the parenthesis are found (note you can get rid of the parenthesis by escaping the outer set of parenthesis rather than the inner (Example here: https://regex101.com/r/eC3uK3/6). There's an optional ", " in a non capturing group, and an optional "\n" in another non-capturing group to handle any newline characters that you may happen across.
This should break your data out into:
'Operator1'
'(value)'
'operator2'
'(value)'
For as many as there are.
You can do this by first splitting then using a regular expression:
[
"operator1(value)",
"operator1(value), operator2(value)",
"operator1(value), operator2(value), operator_n(value)"
].forEach((str)=>{
var results = str
.split(/[,\s]+/) // split operations
.map(s=>s.match(/(\w+)\((\w+)\)/)) // extracts parts of the operations
.filter(Boolean) // ensure there's no error (in case of impure entries)
.map(s=>s.slice(1)); // make the desired result
console.log(results);
});
The following function "check" will achieve what you are looking for, if you want a string instead of an array of result, simply use the .toString() method on the array returned from the function.
function check(str) {
var myRe = /([^(,\s]*)\(([^)]*)\)/g;
var myArray;
var result = [];
while ((myArray = myRe.exec(str)) !== null) {
result.push(`[${myArray[1]}, ${myArray[2]}]`);
};
return result;
}
var check1 = check("operator1(value)");
console.log("check1", check1);
var check2 = check("operator1(value), operator2(value)");
console.log("check2", check2);
var check3 = check("operator1(value), operator2(value), operator_n(value)");
console.log("check3", check3);
This can also be done with a simple split and a for loop.
var data = "operator1(value), operator2(value), operator_n(value)",
ops = data.substring(0, data.length - 1), // Remove the last parenth from the string
arr = ops.split(/\(|\), /),
res = [], n, eN = arr.length;
for (n = 0; n < eN; n += 2) {
res.push([arr[n], arr[n + 1]]);
}
console.log(res);
The code creates a flattened array from a string, and then nests arrays of "operator"/"value" pairs to the result array. Works for older browsers too.
I would like to match a number at the start of each string:
1000_lang sorting_1 ghhgf_1002
1001_lang
100_abcdefg_sgdga_10001_321gg hjdshjdg
So, I will have numbers: 1000, 1001, 100 respectively. Basically, I want to match a number from a string until that number meets first underscore. But numbers can be any length, so if it is 12345_eyquyewuq_32136 df_1999 I need 12345. Don't need any other numbers coming after the first underscore.
^\d+
Get all numbers from the start of the line up to the first non-number
str = "123456_wibble";
patt = /^\d+/;
result = str.match( patt);
result is an array of matches, so as long as there is 1 or more, you've found something
See Mozilla Regular Expressions
This answer is javascript only, but it may be usefull if you don't care about regex:
var str = "1000_lang sorting_1 ghhgf_1002";
var result = str.split("_")[0];
result will hold the first number.
Something like this....
var str = '1000_lang sorting_1 ghhgf_1002',
matches = str.match(/^\d+/)
console.log(matches)
I have the following input:
123456_r.xyz
12345_32423_131.xyz
1235.xyz
237213_21_mmm.xyz
And now I need to fill up the first connected numbers to 8 numbers leading with 0:
00123456_r.xyz
00012345_32423_131.xyz
00001235.xyz
00237213_21_mmm.xyz
My try was to split a the dot, then split (if existing) at the underscore and get the first numbers and fill them up.
But I think there will be a more efficient way with the regex replace function with just the one function, right? How would this look like?
TIA
Matt
I would use a regex, but just for the spliting :
var input = "12345_32423_131.xyz";
var output = "00000000".slice(input.split(/_|\./)[0].length)+input;
Result : "00012345_32423_131.xyz"
EDIT :
the fast, no-splitting but no-regex, solution I gave in comments :
"00000000".slice(Math.min(input.indexOf('_'), input.indexOf('.'))+1)+input
I wouldn't split at all, just replace:
"123456_r.xyz\n12345_32423_131.xyz\n1235.xyz\n237213_21_mmm.xyz".replace(/^[0-9]+/mg, function(a) {return '00000000'.slice(0, 8-a.length)+a})
There's a simple regexp to find the part of the string you want to replace, but you'll need to use a replace function to perform the action you want.
// The array with your strings
var strings = [
'123456_r.xyz',
'12345_32423_131.xyz',
'1235.xyz',
'237213_21_mmm.xyz'
];
// A function that takes a string and a desired length
function addLeadingZeros(string, desiredLength){
// ...and, while the length of the string is less than desired..
while(string.length < desiredLength){
// ...replaces is it with '0' plus itself
string = '0' + string;
}
// And returns that string
return string;
}
// So for each items in 'strings'...
for(var i = 0; i < strings.length; ++i){
// ...replace any instance of the regex (1 or more (+) integers (\d) at the start (^))...
strings[i] = strings[i].replace(/^\d+/, function replace(capturedIntegers){
// ...with the function defined above, specifying 8 as our desired length.
return addLeadingZeros(capturedIntegers, 8);
});
};
// Output to screen!
document.write(JSON.toString(strings));
If I have a string like "something12" or "something102", how would I use a regex in javascript to return just the number parts?
Regular expressions:
var numberPattern = /\d+/g;
'something102asdfkj1948948'.match( numberPattern )
This would return an Array with two elements inside, '102' and '1948948'. Operate as you wish. If it doesn't match any it will return null.
To concatenate them:
'something102asdfkj1948948'.match( numberPattern ).join('')
Assuming you're not dealing with complex decimals, this should suffice I suppose.
You could also strip all the non-digit characters (\D or [^0-9]):
let word_With_Numbers = 'abc123c def4567hij89'
let word_Without_Numbers = word_With_Numbers.replace(/\D/g, '');
console.log(word_Without_Numbers)
For number with decimal fraction and minus sign, I use this snippet:
const NUMERIC_REGEXP = /[-]{0,1}[\d]*[.]{0,1}[\d]+/g;
const numbers = '2.2px 3.1px 4px -7.6px obj.key'.match(NUMERIC_REGEXP)
console.log(numbers); // ["2.2", "3.1", "4", "-7.6"]
Update: - 7/9/2018
Found a tool which allows you to edit regular expression visually: JavaScript Regular Expression Parser & Visualizer.
Update:
Here's another one with which you can even debugger regexp: Online regex tester and debugger.
Update:
Another one: RegExr.
Update:
Regexper and Regex Pal.
If you want only digits:
var value = '675-805-714';
var numberPattern = /\d+/g;
value = value.match( numberPattern ).join([]);
alert(value);
//Show: 675805714
Now you get the digits joined
I guess you want to get number(s) from the string. In which case, you can use the following:
// Returns an array of numbers located in the string
function get_numbers(input) {
return input.match(/[0-9]+/g);
}
var first_test = get_numbers('something102');
var second_test = get_numbers('something102or12');
var third_test = get_numbers('no numbers here!');
alert(first_test); // [102]
alert(second_test); // [102,12]
alert(third_test); // null
IMO the #3 answer at this time by Chen Dachao is the right way to go if you want to capture any kind of number, but the regular expression can be shortened from:
/[-]{0,1}[\d]*[\.]{0,1}[\d]+/g
to:
/-?\d*\.?\d+/g
For example, this code:
"lin-grad.ient(217deg,rgba(255, 0, 0, -0.8), rgba(-255,0,0,0) 70.71%)".match(/-?\d*\.?\d+/g)
generates this array:
["217","255","0","0","-0.8","-255","0","0","0","70.71"]
I've butchered an MDN linear gradient example so that it fully tests the regexp and doesn't need to scroll here. I think I've included all the possibilities in terms of negative numbers, decimals, unit suffixes like deg and %, inconsistent comma and space usage, and the extra dot/period and hyphen/dash characters within the text "lin-grad.ient". Please let me know if I'm missing something. The only thing I can see that it does not handle is a badly formed decimal number like "0..8".
If you really want an array of numbers, you can convert the entire array in the same line of code:
array = whatever.match(/-?\d*\.?\d+/g).map(Number);
My particular code, which is parsing CSS functions, doesn't need to worry about the non-numeric use of the dot/period character, so the regular expression can be even simpler:
/-?[\d\.]+/g
var result = input.match(/\d+/g).join([])
Using split and regex :
var str = "fooBar0123".split(/(\d+)/);
console.log(str[0]); // fooBar
console.log(str[1]); // 0123
The answers given don't actually match your question, which implied a trailing number. Also, remember that you're getting a string back; if you actually need a number, cast the result:
item=item.replace('^.*\D(\d*)$', '$1');
if (!/^\d+$/.test(item)) throw 'parse error: number not found';
item=Number(item);
If you're dealing with numeric item ids on a web page, your code could also usefully accept an Element, extracting the number from its id (or its first parent with an id); if you've an Event handy, you can likely get the Element from that, too.
As per #Syntle's answer, if you have only non numeric characters you'll get an Uncaught TypeError: Cannot read property 'join' of null.
This will prevent errors if no matches are found and return an empty string:
('something'.match( /\d+/g )||[]).join('')
Here is the solution to convert the string to valid plain or decimal numbers using Regex:
//something123.777.321something to 123.777321
const str = 'something123.777.321something';
let initialValue = str.replace(/[^0-9.]+/, '');
//initialValue = '123.777.321';
//characterCount just count the characters in a given string
if (characterCount(intitialValue, '.') > 1) {
const splitedValue = intitialValue.split('.');
//splittedValue = ['123','777','321'];
intitialValue = splitedValue.shift() + '.' + splitedValue.join('');
//result i.e. initialValue = '123.777321'
}
If you want dot/comma separated numbers also, then:
\d*\.?\d*
or
[0-9]*\.?[0-9]*
You can use https://regex101.com/ to test your regexes.
Everything that other solutions have, but with a little validation
// value = '675-805-714'
const validateNumberInput = (value) => {
let numberPattern = /\d+/g
let numbers = value.match(numberPattern)
if (numbers === null) {
return 0
}
return parseInt(numbers.join([]))
}
// 675805714
One liner
I you do not care about decimal numbers and only need the digits, I think this one liner is rather elegant:
/**
* #param {String} str
* #returns {String} - All digits from the given `str`
*/
const getDigitsInString = (str) => str.replace(/[^\d]*/g, '');
console.log([
'?,!_:/42\`"^',
'A 0 B 1 C 2 D 3 E',
' 4 twenty 20 ',
'1413/12/11',
'16:20:42:01'
].map((str) => getDigitsInString(str)));
Simple explanation:
\d matches any digit from 0 to 9
[^n] matches anything that is not n
* matches 0 times or more the predecessor
( It is an attempt to match a whole block of non-digits all at once )
g at the end, indicates that the regex is global to the entire string and that we will not stop at the first occurrence but match every occurrence within it
Together those rules match anything but digits, which we replace by an empty strings. Thus, resulting in a string containing digits only.