Regex to allow numbers, plus symbol, minus symbol and brackets - javascript

I am trying to create a regex that allows only the following 0-9, plus symbol, minus symbol and brackets (). No limitations on length of each of the mentioned. So far I have this but it does not seem to work.
/^[0-9 -+]+$/

Hyphen - has to be at the end of charlist, else it means interval.
/^[0-9 ()+-]+$/
0-9 is possible to write shortly as \d
/^[\d ()+-]+$/

This should work for you:
^[\d\(\)\-+]+$
^ -> start of string
\d -> same as [0-9]
+ -> one or more repetitions
$ -> end of string
DEMO
var re = /^[\d\(\)\-+]+$/m;
var str = ['09+()1213+-','fa(-ds'];
var m;
var result = "";
for(var i = 0; i < str.length; i++) {
if ((m = re.exec(str[i])) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
result += "\""+str[i]+ "\"" + " is matched:" + (m != null) + "</br>";
}
document.getElementById("results").innerHTML = result
<div id="results"></div>

To match digits, +, -, (, and ) use:
[+()\d-]+
The trick is the position of the characters inside the character class.
if (/^[+()\d-]+$/.test(text)) {
} else {
}

var re = /^[\w\(\)\-\!\+\*\&\%\$#\#\[\]\{\}\<\>\s]+$/m;
var str = ['09+()1213+-[#test#gmail{}<>','fa(-ds'];
var m;
var result = "";
for(var i = 0; i < str.length; i++) {
if ((m = re.exec(str[i])) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
result += "\""+str[i]+ "\"" + " is matched:" + (m != null) + "</br>";
}
document.getElementById("results").innerHTML = result
<div id="results"></div>

[\d\(\)\+\-\(\)]
That should do it.
EDIT: But since some agree the escaping is too much, here ya go:
[\d+()-]

Related

Invert capturing groups in regular expression

Given this (note the capturing groups):
/^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/
I want this (note the capturing groups have been inverted):
/^(\w+\[\w+\]\[\w+\]\[)\d+(\]\[\w+\]\[)\d+(\]\[\w+\])$/
What I have attempted:
str = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString()
noncaptured = [];
captured = [];
insideCapture = false;
for (var i = 0, position = 1; i < str.length; i++) {
if( str.charAt(i) != '(' && insideCapture == false ){
noncaptured.push([position, str.charAt(i) ] );
} else {
if( str.charAt(i) != '(' ){
position += 1;
}
captured.push([position, str.charAt(i) ]);
insideCapture = true;
if( str.charAt(i) == ')' ){
captured.push([position, str.charAt(i)]);
insideCapture = false;
position += 1;
}
}
}
var arr = captured.concat(insideCapture);
arr.sort(function(){
if (a[0] === b[0]) {
return 0;
}
else {
return (a[0] < b[0]) ? -1 : 1;
}
})
I am looking for a clean algorithm. ES6 solution welcome.
Even if I'm not 100% sure the next will work on all the cases you may need, this can be an alternative approach: Reverse all parentheses, and add parentheses after ^ and before $
const str1 = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const str2 = /^\w+(\[\w+\])\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const str3 = /^(\w+\[\w+\]\[\w+\]\[\d+\]\[\w+\]\[\d+\]\[\w+\])$/.toString();
const str4 = /^\w+\[\w+\]\[\w+\]\[\d+\]\[\w+\]\[\d+\]\[\w+\]$/.toString();
const replaceMap = {"(": ")", ")": "(", "^": "^(", "$": ")$"};
const reverse = (str) =>
{
return str.replace(/[(,),^, $]/g, function(match)
{
return replaceMap[match];
});
}
console.log(reverse(str1));
console.log(reverse(str2));
console.log(reverse(str3));
console.log(reverse(str4));
Assuming that there won't be nested parentheses, as in the example, I'd slice out the parts of the string between the leading /^ and the trailing $/, then use a regular expression to capture non-parentheses characters, and replace with that group surrounded by parentheses. Also, after the non-parentheses characters, optionally match (s, followed by non-parentheses characters, followed by ), and if that group matches, replace with just that group (without parentheses):
([^(]+)(?:\(([^)]+)\))?
Replace with
($1)$2
https://regex101.com/r/gLrHsH/1
const str = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const sliced = str.slice(2, str.length - 2);
const output = '/^' + sliced.replace(/([^(]+)(?:\(([^)]+)\))?/g, '($1)$2') + '$/';
console.log(output);
([^(]+)(?:\(([^)]+)\))?
means:
([^(]+) - Non-( characters
(?:\(([^)]+)\))? Optional non-capturing group containing:
\( - Leading (
([^)]+) - Non-) characters, captured in a group
\) - Trailing )

Convert sentence or camelCase word to spinal-case

I am trying to convert both sentence case and camel case to spinal case.
I am able to change camel case to by adding a space before every capital letter, but when I apply it to sentences with capital letters after spaces, I get extra spacing.
Here is my function so far :
function spinalCase(str) {
var noCamel = str.replace(/([A-Z])/g, ' $1');
var newStr = noCamel.replace(/\s|_/g, "-");
return newStr.toLowerCase();
}
spinalCase("makeThisSpinal"); //returns make-this-spinal
spinalCase("Make This Spinal"); //returns -make--this--spinal
Get lodash, specifically, https://lodash.com/docs#kebabCase.
_.kebabCase('makeThisSpinal') // make-this-spinal
_.kebabCase('Even Sentences Work') // even-sentences-work
Instead of:
var noCamel = str.replace(/([A-Z])/g, ' $1');
Try:
var noCamel = str.replace(/(\B[A-Z])/g, ' $1');
It's because you're replacing all capital letters with a space and its lowercase letter. So in your sentence, you're getting two spaces before this and spinal.
What you can do is replace all uppercase letters with "-$1" and then just remove all spaces from the string.
function spinalCase(str) {
var noCamel = str.replace(/([a-z](?=[A-Z]))/g, '$1 ')
var newStr = noCamel.replace(/\s|_/g, "-");
return newStr.toLowerCase();
}
spinalCase("makeThisSpinal"); //returns make-this-spinal
spinalCase("Make This Spinal"); //returns -make-this-spinal
Instead of str.replace(/([A-Z])/g, ' $1') for the camel case split, you should use str.replace(/([a-z](?=[A-Z]))/g, '$1 ') which will space out each word regardless of case.
Here's my solution, perhaps you will find it good reference:
function spinalCase(str) {
var newStr = str[0];
for (var j = 1; j < str.length; j++) {
// if not a letter make a dash
if (str[j].search(/\W/) !== -1 || str[j] === "_") {
newStr += "-";
}
// if a Capital letter is found
else if (str[j] === str[j].toUpperCase()) {
// and preceded by a letter or '_'
if (str[j-1].search(/\w/) !== -1 && str[j-1] !== "_") {
// insert '-' and carry on
newStr += "-";
newStr += str[j];
}
else {
newStr += str[j];
}
}
else {
newStr += str[j];
}
}
newStr = newStr.toLowerCase();
return newStr;
}

Debugging JavaScript for Palindrome Function

function palindrome(str) {
str = str.replace(' ', '');
str = str.replace(',', '');
str = str.replace('.', '');
str = str.toLowerCase();
if (str.length % 2 === 0) {
var x = 0;
while (x < (str.length - x)) {
if (str.charAt(x) === str.charAt((str.length - x) - 1)) {
x++;
} else {
return false;
}
}
return true;
} else {
var y = 0;
while (y < (str.length - y - 1)) {
if (str.charAt(y) === str.charAt((str.length - y) - 1)) {
y++;
} else {
return false;
}
}
return true;
}
}
palindrome("eye");
This may not be the most effecient way of solving this, but I begin by remove extraneous characters, then I used an if/else to split out even and odd string lengths. Within each, I only check equality of characters up through the middle of the word - since past that would be repetitious.
However, after multiple changes and looking into other solutions for the problem, I still cannot get mine to pass for a particular case: palindrome("never odd or even")
If it helps, it passes for "race car" and "almostomla" and "eye".
Thanks in advance!
The problem is that the native replace Javascript function is only replacing a single occurrence in the string. Use Regex to account for all of the matches within the string.
However, keep in mind that the "." character is used in Regex as a wildcard so you need to escape it with a backslash to tell Regex you're specifically looking for the "." character. See this JSFiddle as an example: https://jsfiddle.net/on333yf9/3/
function palindrome(str) {
str = str.replace(/ /g, '');
str = str.replace(/,/g, '');
str = str.replace(/\./g, '');
str = str.toLowerCase();
if (str.length % 2 === 0) {
var x = 0;
while (x < (str.length - x)) {
if (str.charAt(x) === str.charAt((str.length - x) - 1)) {
x++;
} else {
return false;
}
}
return true;
} else {
var y = 0;
while (y < (str.length - y - 1)) {
if (str.charAt(y) === str.charAt((str.length - y) - 1)) {
y++;
} else {
return false;
}
}
return true;
}
}
The problem is because of the following lines:
str = str.replace(' ', '');
str = str.replace(',', '');
str = str.replace('.', '');
It does replace all white spaces, commas or dots globally, it just replaces one space, comma and dot, if it's there. You have to find all spaces, commas and dots and remove them. This is what you can do,
str = str.replace(/ /g, '');
str = str.replace(/,/g, '');
str = str.replace(/./g, '');
The g character means to repeat the search through the entire string. Read about this, and other RegEx modifiers available in JavaScript here.
Edited:
You can do something like this:
if(str.replace(/ /g, '').length != 0){
str = str.replace(/ /g, '');
}
if(str.replace(/,/g, '').length != 0){
str = str.replace(/,/g, '');
}
if(str.replace(/\./g, '').length != 0){
str = str.replace(/\./g, '');
}
Unless you want to write your own code why not user reverse/join?
function palindrome(str)
{
str = str.split(' ').join('');
str = str.split(',').join('');
str = str.split('.').join('');
str = str.toLowerCase();
if (str.split('').reverse().join('') == str)
{
return true;
}
else
{
return false;
}
}
palindrome("never odd or even");

Formatting negative numbers with regex

I need to format my numbers and I am using regex /(?=(?!^)(?:\d{3})+$)/g, to replace and insert , where it is necessary. But currently I have an issue with negative {3} 000 numbers, so comma is added after minus.
What am I doing wrong?
'-200'.replace(/(?=(?!^)(?:\d{3})+$)/g, ',')
returns: -,200
correct: -200
'-2000'.replace(/(?=(?!^)(?:\d{3})+$)/g, ',')
returns: -2,000
correct: -2,000
You can use this regex:
var num = '-2000';
var repl = num.replace(/(\d)(?=(?:\d{3})+$)/m, '$1,');
or
var repl = num.replace(/(?=(?:\B\d{3})+$)/m, ',');
RegEx Demo
I suggest you to replace ^ with \b
(?=(?!\b)(?:\d{3})+$)
DEMO
(?!^) asserts that we are not at the start only, but (?!\b) asserts that we are not between a word char and a non-word character (vice-versa).
Example:
alert('-200'.replace(/(?=(?!\b)(?:\d{3})+$)/g, ','))
alert('-2000'.replace(/(?=(?!\b)(?:\d{3})+$)/g, ','))
To handle signed numbers, I'd recommend using something else than a regex
function formatInteger(num) {
var str = ('' + num).split('.')[0];
var sign = (str.charAt(0) === '-') && '-' || '';
if (sign) {
str = str.substr(1);
}
return sign + str.split('').reduceRight(function (result, char) {
if (result.length % 4 === 0) {
char += ',';
}
return char + result;
}, '').slice(0, -1);
}
If you feed this function a float, it will be truncated.
formatInteger(123456.123); // "123,456"
formatInteger(-1594504924) // "-1,594,504,924"
An other way:
var nb = '-2000000';
nb = nb.split(/\B/).reduce(function(p, c, i, a) {
return p + ((a.length-i)%3 ? c : ',' + c);
});

Is there a way I can change the contents of a variable in Camel Case to space separated words?

I have a variable which contains this:
var a = "hotelRoomNumber";
Is there a way I can create a new variable from this that contains: "Hotel Room Number" ? I need to do a split on the uppercase character but I've not seen this done anywhere before.
Well, you could use a regex, but it's simpler just to build a new string:
var a = "hotelRoomNumber";
var b = '';
if (a.length > 0) {
b += a[0].toUpperCase();
for (var i = 1; i != a.length; ++i) {
b += a[i] === a[i].toUpperCase() ? ' ' + a[i] : a[i];
}
}
// Now b === "Hotel Room Number"
var str = "mySampleString";
str = str.replace(/([A-Z])/g, ' $1').replace(/^./, function(str){ return str.toUpperCase(); });
http://jsfiddle.net/PrashantJ/zX8RL/1/
I have made a function here:
http://jsfiddle.net/wZf6Z/2/
function camelToSpaceSeperated(string)
{
var char, i, spaceSeperated = '';
// iterate through each char
for (i = 0; i < string.length; i++) {
char = string.charAt(i); // current char
if (i > 0 && char === char.toUpperCase()) { // if is uppercase
spaceSeperated += ' ' + char;
} else {
spaceSeperated += char;
}
}
// Make the first char uppercase
spaceSeperated = spaceSeperated.charAt(0).toUpperCase() + spaceSeperated.substr(1);
return spaceSeperated;
}
The general idea is to iterate through each char in the string, check if the current char is already uppercased, if so then prepend a space to it.

Categories

Resources