Getting second digit in a string using Javascript + Regex? - javascript

I'm wondering how I can get the second digit of a string where we don't know the number of digits the second number will be and without using splice or substring.
Ex. Channel.0.This.13
Should Return: 13
I've seen a few similar questions but they
typically know the number of digits the second number will be or
use splicing and substring, which I do not want to use in this case.
I appreciate the help :)

You could use String.prototype.match
In case that the string does not have any number, which matches will return null, you should use optional chaining ?. for a safer array index access
const str = "Channel.0.This.13";
const res = str.match(/\d+/g)?.[1];
console.log(res);

Use this regex (\d*)$. This will return only group with numbers which in the end of the string.

try this:
^[^\d]*\d+[^\d]+(\d+).*
Example:
const secondDigit = "Channel.0.This.13".match(/^[^\d]*\d+[^\d]+(\d+).*/).pop();
console.log(Number(secondDigit)); // 13

Assuming the original string contains only alphabets, numbers and '.' (in between),
Here is my solution (Pseudo code):
String givenString;
regex=/([0-9]+)(\.[a-zA-Z]+)?(\.[0-9]+)/;
//below code will return an array or null (if no second number is present)
match=givenString.match(regex);
//access last element of array. It will be like '.13' , just remove '.' and you are good to go
match.pop()
Javascript Regex Docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges

String.prototype.match() returns an array whose contents depend on the presence or absence of the global (g) flag, or null
const input1 = "Channel.0.This.13",
input2 = "Channel.0.This",
input3 = "Channel.This.";
const digitMatch = function (input) {
const digits = input.match(/\d+/g);
return (digits && digits[1]) || "Not Found";
};
console.log(digitMatch(input1));
console.log(digitMatch(input2));
console.log(digitMatch(input3));
if no matches are found.

It will help .*?\d+.*?(\d+).*$
"Channel.0.This.13.Channel.0.This.56".match(/.*?\d+.*?(\d+).*$/).pop()
// Output: 13
"Channel.0.This.13".match(/.*?\d+.*?(\d+).*$/).pop()
// Output: 13

You can reference the regex .match() key. str.match(reg)[1]
const str1 = 'Channel.0.This.13'
const str2 = 'some.otherStrin8..'
const str3 = '65 people.For.&*=20.them,98'
const regex = /\d+/g
function matchSecond(str, reg) {
str.match(reg)[1] ? output = str.match(reg)[1] : output = false
return output;
}
console.log(matchSecond(str1,regex))
console.log(matchSecond(str2,regex))
console.log(matchSecond(str3,regex))

Related

Javascript split by numbers using regex

I'm trying to come up with a regex that will do following.
I have a string
var input_string = "E100T10P200E3000T3S10";
var output=input_string.split(**Trying to find this**);
this should give an array with all the letters in order with repetitions
output = ["E","T","P","E","T","S"]
See below. \d+ means one or more digits; filter (x => x) removes empty strings that can appear in the beginning or the end of the array if the input string begins or ends with digits.
var input_string = "E100T10P200E3000T3S10";
var output = input_string.split (/\d+/).filter (x => x);
console.log (output);
We can try just matching for capital letters here:
var input_string = "E100T10P200E3000T3S10";
var output = input_string.match(/[A-Z]/g);
console.log(output);
Another approach is spread the string to array and use isNaN as filter callback
var input_string = "E100T10P200E3000T3S10";
var output = [...input_string].filter(isNaN);
console.log(output);
You can use regex replace method. First replace all the digits with empty string and then split the resultant string.
const input_string = 'E100T10P200E3000T3S10';
const ret = input_string.replace(/\d/g, '').split('');
console.log(ret);

JavaScript Split with RegEx without Global Match

I have an expression.
var expression = "Q101='You will have an answer here like a string for instance.'"
I have a regular expression that searches the expression.
var regEx = new regExp(/=|<>|like/)
I want to split the expression using the regular expression.
var result = expression.split(regExp)
This will return the following:
["Q101", "'You will have an answer here ", " a string for instance'"]
This is not what I want.
I should have:
["Q101", "'You will have an answer here like a string for instance'"]
How do I use the regular expression above to split only on the first match?
Since you only want to grab the two parts either side of the first delimiter it might be easier to use String.match and discard the whole match:
var expression = "Q101='You will have an answer here like a string for instance.'";
var parts = expression.match(/^(.*?)(?:=|<>|like)(.*)$/);
parts.shift();
console.log(parts);
expression = "Q101like'This answer uses like twice'";
parts = expression.match(/^(.*?)(?:=|<>|like)(.*)$/);
parts.shift();
console.log(parts);
JavaScript's split method won't quite do what you want, because it will either split on all matches, or stop after N matches. You need an extra step to find the first match, then split once by the first match using a custom function:
function splitMatch(string, match) {
var splitString = match[0];
var result = [
expression.slice(0, match.index),
expression.slice(match.index + splitString.length)
];
return result;
}
var expression = "Q101='You will have an answer here like a string for instance.'"
var regEx = new RegExp(/=|<>|like/)
var match = regEx.exec(expression)
if (match) {
var result = splitMatch(expression, match);
console.log(result);
}
While JavaScript's split method does have an optional limit parameter, it simply discards the parts of the result that make it too long (unlike, e.g. Python's split). To do this in JS, you'll need to split it manually, considering the length of the match —
const exp = "Q101='You will have an answer here like a string for instance.'"
const splitRxp = /=|<>|like/
const splitPos = exp.search(splitRxp)
const splitStr = exp.match(splitRxp)[0]
const result = splitPos != -1 ? (
[
exp.substring(0, splitPos),
exp.substring(splitPos + splitStr.length),
]
) : (
null
);
console.log(result)

Return unique digits of a time format string using regex

Need to create a regex pattern that will return unique digits before or after a : symbol, using String.match. It should only return the digit, not the : symbol. PS: I know there is other (maybe easier) ways to do this, but I want to use regex for learning purposes
let s;
let regex = /(^\d:)(:\d$)/g // I tried this, off course it didn't work
s = '12:34'
s.match(regex) // return null
s = '1:34'
s.match(regex) // return [1]
s = '12:4'
s.match(regex) // return [4]
s = '1:4'
s.match(regex) // return [1,4]
Try using this:
let regex = /(((?<=:)\d(?!\d))|((?<!\d)\d(?=:)))/g
This will match the patterns you want!
Here's a reference for Regex.
let s;
let regex = /(((?<=:)\d(?!\d))|((?<!\d)\d(?=:)))/g
s = '12:34'
console.log(s.match(regex)) // return null
s = '1:34'
console.log(s.match(regex)) // return [1]
s = '12:4'
console.log(s.match(regex)) // return [4]
s = '1:4'
console.log(s.match(regex)) // return [1,4]
Example done in JavaScript. The 2nd regex is the most simple, it matches a digit followed by a colon, followed by a digit (you could use this with the g flag if there is more than one occurrence in your text).
1st regex matches the entire string and MAY have one or more characters before the 1st digit and one or more characters after the 2nd one. This will only capture one occurrence for the entire string.
let regex1 = /^.*(\d):(\d).*$/;
let regex2 = /(\d):(\d)/;
console.log("Make sure the entire string only contains one instance");
['12:34', '1:34', '12:4', '1:4' ].forEach( (s) => console.log(s.match(regex1) ));
console.log("Match the first instance found");
['12:34', '1:34', '12:4', '1:4' ].forEach( (s) => console.log(s.match(regex2) ));
Not sure what do you mean by "unique".
But if you want to just get numbers then you can use + or * quantifiers.
/^(\d+):(\d+)$/

Javascript split only once and ignore the rest

I am parsing some key value pairs that are separated by colons. The problem I am having is that in the value section there are colons that I want to ignore but the split function is picking them up anyway.
sample:
Name: my name
description: this string is not escaped: i hate these colons
date: a date
On the individual lines I tried this line.split(/:/, 1) but it only matched the value part of the data. Next I tried line.split(/:/, 2) but that gave me ['description', 'this string is not escaped'] and I need the whole string.
Thanks for the help!
a = line.split(/:/);
key = a.shift();
val = a.join(':');
Use the greedy operator (?) to only split the first instance.
line.split(/: (.+)?/, 2);
If you prefer an alternative to regexp consider this:
var split = line.split(':');
var key = split[0];
var val = split.slice(1).join(":");
Reference: split, slice, join.
Slightly more elegant:
a = line.match(/(.*?):(.*)/);
key = a[1];
val = a[2];
May be this approach will be the best for such purpose:
var a = line.match(/([^:\s]+)\s*:\s*(.*)/);
var key = a[1];
var val = a[2];
So, you can use tabulations in your config/data files of such structure and also not worry about spaces before or after your name-value delimiter ':'.
Or you can use primitive and fast string functions indexOf and substr to reach your goal in, I think, the fastest way (by CPU and RAM)
for ( ... line ... ) {
var delimPos = line.indexOf(':');
if (delimPos <= 0) {
continue; // Something wrong with this "line"
}
var key = line.substr(0, delimPos).trim();
var val = line.substr(delimPos + 1).trim();
// Do all you need with this key: val
}
Split string in two at first occurrence
To split a string with multiple i.e. columns : only at the first column occurrence
use Positive Lookbehind (?<=)
const a = "Description: this: is: nice";
const b = "Name: My Name";
console.log(a.split(/(?<=^[^:]*):/)); // ["Description", " this: is: nice"]
console.log(b.split(/(?<=^[^:]*):/)); // ["Name", " My Name"]
it basically consumes from Start of string ^ everything that is not a column [^:] zero or more times *. Once the positive lookbehind is done, finally matches the column :.
If you additionally want to remove one or more whitespaces following the column,
use /(?<=^[^:]*): */
Explanation on Regex101.com
function splitOnce(str, sep) {
const idx = str.indexOf(sep);
return [str.slice(0, idx), str.slice(idx+1)];
}
splitOnce("description: this string is not escaped: i hate these colons", ":")

Regex using javascript to return just numbers

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.

Categories

Resources