var scale = $('#'+fields[i].id+'-scale').val();
var decimalOnly = '/^\s*-?[1-9]\d*(\,\d{1,'+scale+'})?\s*$/';
if(fields[i].value != "" && !(fields[i].value).match(decimalOnly)) {
$(fields[i]).addClass('form-attr-error');
result = false;
}
else {
$(fields[i]).removeClass('form-attr-error');
}
In the above RegEx passing the 'scale' placeholder value & comparing value.match(RegEx) it's not working.
But it as working like this
value.match(/^\s*-?[1-9]\d*(\,\d{1,2})?\s*$/);
please help me on this how can i pass place holder value in place of '2'.
.match will automatically convert a string argument into a regexp; if you want to be explicit about it, you can use the RegExp constructor. But note that slashes are not part of the regexp, they are part of the regexp literal. I.e. these will do the same thing:
foo.match(/a/)
foo.match("a")
foo.match(new RegExp("a"))
These will all do the same thing that is different from the first set:
foo.match(/\/a\/)
foo.match("/a/")
foo.match(new RegExp("/a/"))
The former ones will match one-letter sequence a; the latter ones will match the three-letter sequence /a/.
tl;dr: get rid of slashes in decimalOnly.
Related
I can get the source of a regex when it's defined separately. For example:
let r1 = new RegExp("el*");
console.log(r1.source);
// el*
Or:
let r2 = /el*/;
console.log(r2.source);
// el*
Is there a way to extract that if the regex isn't defined separately? For example, something along the lines of:
let m = "Hello".match(/el*/);
console.log(m.source?);
No,
quoting the documents of the match() function
Return value
An Array whose contents depend on the presence or absence of the
global (g) flag, or null if no matches are found.
So the return value is an array (you can test it by Array.isArray(m)// true)
However, the returned array has some extra information about the ocurred match (like groups, index and original input) but none of them include the original regex used to get the match
So there is no way to get that information from the match because its not returned by the matching function
The match result by itself cannot lead to the original regex, simply because different regexes can lead to the same result, even on the same string. Take for example the string "abcd" - all the following regexes: /abcd/, /a..d/ /a.*/ and many more, would match the string exactly the same way.
The only way you could retrive the original regex is if a reference to the regex was literally stored by the match() method inside the returned object. There is no reason to think that's the case, but you can implement your own match function that would do. Something like
function myMatch(str, regex) {
var match = str.match(regex);
if (match === null) {
match = [null];
}
match.source = regex;
return match;
}
var name = "AlbERt EINstEiN";
function nameChanger(oldName) {
var finalName = oldName;
// Your code goes here!
finalName = oldName.toLowerCase();
finalName = finalName.replace(finalName.charAt(0), finalName.charAt(0).toUpperCase());
for(i = 0; i < finalName.length; i++) {
if (finalName.charAt(i) === " ")
finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
}
// Don't delete this line!
return finalName;
};
// Did your code work? The line below will tell you!
console.log(nameChanger(name));
My code as is, returns 'Albert einstein'. I'm wondering where I've gone wrong?
If I add in
console.log(finalName.charAt(i+1));
AFTER the if statement, and comment out the rest, it prints 'e', so it recognizes charAt(i+1) like it should... I just cannot get it to capitalize that first letter of the 2nd word.
There are two problems with your code sample. I'll go through them one-by-one.
Strings are immutable
This doesn't work the way you think it does:
finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
You need to change it to:
finalName = finalName.replace(finalName.charAt(i+1), finalName.charAt(i+1).toUpperCase());
In JavaScript, strings are immutable. This means that once a string is created, it can't be changed. That might sound strange since in your code, it seems like you are changing the string finalName throughout the loop with methods like replace().
But in reality, you aren't actually changing it! The replace() function takes an input string, does the replacement, and produces a new output string, since it isn't actually allowed to change the input string (immutability). So, tl;dr, if you don't capture the output of replace() by assigning it to a variable, the replaced string is lost.
Incidentally, it's okay to assign it back to the original variable name, which is why you can do finalName = finalName.replace(...).
Replace is greedy
The other problem you'll run into is when you use replace(), you'll be replacing all of the matching characters in the string, not just the ones at the position you are examining. This is because replace() is greedy - if you tell it to replace 'e' with 'E', it'll replace all of them!
What you need to do, essentially, is:
Find a space character (you've already done this)
Grab all of the string up to and including the space; this "side" of the string is good.
Convert the very next letter to uppercase, but only that letter.
Grab the rest of the string, past the letter you converted.
Put all three pieces together (beginning of string, capitalized letter, end of string).
The slice() method will do what you want:
if (finalName.charAt(i) === " ") {
// Get ONLY the letter after the space
var startLetter = finalName.slice(i+1, i+2);
// Concatenate the string up to the letter + the letter uppercased + the rest of the string
finalName = finalName.slice(0, i+1) + startLetter.toUpperCase() + finalName.slice(i+2);
}
Another option is regular expression (regex), which the other answers mentioned. This is probably a better option, since it's a lot cleaner. But, if you're learning programming for the first time, it's easier to understand this manual string work by writing the raw loops. Later you can mess with the efficient way to do it.
Working jsfiddle: http://jsfiddle.net/9dLw1Lfx/
Further reading:
Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?
slice() method
You can simplify this down a lot if you pass a RegExp /pattern/flags and a function into str.replace instead of using substrings
function nameChanger(oldName) {
var lowerCase = oldName.toLowerCase(),
titleCase = lowerCase.replace(/\b./g, function ($0) {return $0.toUpperCase()});
return titleCase;
};
In this example I've applied the change to any character . after a word boundary \b, but you may want the more specific /(^| )./g
Another good answer to this question is to use RegEx to do this for you.
var re = /(\b[a-z](?!\s))/g;
var s = "fort collins, croton-on-hudson, harper's ferry, coeur d'alene, o'fallon";
s = s.replace(re, function(x){return x.toUpperCase();});
console.log(s); // "Fort Collins, Croton-On-Hudson, Harper's Ferry, Coeur D'Alene, O'Fallon"
The regular expression being used may need to be changed up slightly, but this should give you an idea of what you can do with regular expressions
Capitalize Letters with JavaScript
The problem is twofold:
1) You need to return a value for finalName.replace, as the method returns an element but doesn't alter the one on which it's predicated.
2) You're not iterating through the string values, so you're only changing the first word. Don't you want to change every word so it's in lower case capitalized?
This code would serve you better:
var name = "AlbERt EINstEiN";
function nameChanger(oldName) {
// Your code goes here!
var finalName = [];
oldName.toLowerCase().split(" ").forEach(function(word) {
newWord = word.replace(word.charAt(0), word.charAt(0).toUpperCase());
finalName.push(newWord);
});
// Don't delete this line!
return finalName.join(" ");
};
// Did your code work? The line below will tell you!
console.log(nameChanger(name));
if (finalName.charAt(i) === " ")
Shouldn't it be
if (finalName.charAt(i) == " ")
Doesn't === check if the object types are equal which should not be since one it a char and the other a string.
I have string "club160", but I want to get string "club-160", how I can do this? I need to use split() func? For split I need delimiter but there is no comma, or space.
Can somebody help me?
You can do this using a regular expression and a replace operation:
var s = "club160"
var result = s.replace(/([a-z])([0-9])/i, '$1-$2')
But this only replaces something like aaa111 to aaa-111, 111aaa will stay 111aaa
If the string always contains at least one digit or letter, consider:
var s = 'club160';
s.match(/(\d+)|([a-z]+)/ig).join('-'); // club-160
var t = '160club';
t.match(/(\d+)|([a-z]+)/ig).join('-'); // 160-club
It doesn't care about order or how many groups of letters and numbers are present. However, it requires at least one letter or number in the string, otherwise it will throw an error.
As a function, dealing with errors:
function specialSplit(s) {
// Make sure string has at least one letter or digit
if (/\d|[a-z]/i.test(s)) {
return s.match(/(\d+)|([a-z]+)/ig).join('-');
}
// Otherwise return undefined
}
I have the following snippet. I want to find the appearance of a, but it does not work. How can I put the variable right?
var string1 = 'asdgghjajakhakhdsadsafdgawerwweadf';
var string2 = 'a';
string1.match('/' + string2 + '/g').length;
You need to use the RegExp constructor instead of a regex literal.
var string = 'asdgghjjkhkh';
var string2 = 'a';
var regex = new RegExp( string2, 'g' );
string.match(regex);
If you didn't need the global modifier, then you could just pass string2, and .match() will create the regex for you.
string.match( string2 );
If you are merely looking to check whether a string contains another string, then your best bet is simply to use match() without a regex.
You may object: But I need a regex to check for classes, like \s, to define complicated patterns, etc..
In that case: You will need change the syntax even more, double-escaping your classes and dropping starting/ending / regex indicator symbols.
Imagine this regex...
someString.match(/\bcool|tubular\b);
The exact equivalent of this, when using a new new RegExp(), is...
someStringRegex = new RegExp('\\bcool|tubular\\b');
Two things happened in this transition:
Drop the opening and closing / (otherwise, your regex will fail).
Double escape your character classes, like \b becomes \\b for word borders, and \w becomes \\w for whitespace, etc. (otherwise, your regex will fail).
Here is another example-
//confirm whether a string contains target at its end (both are variables in the function below, e.g. confirm whether str "Abstraction" contains target "action" at the end).
function confirmEnding(string, target) {
let regex = new RegExp(target);
return regex.test(string);
};
Say I wanted to make the following re-usable:
function replace_foo(target, replacement) {
return target.replace("string_to_replace",replacement);
}
I might do something like this:
function replace_foo(target, string_to_replace, replacement) {
return target.replace(string_to_replace,replacement);
}
With string literals this is easy enough. But what if I want to get a little more tricky with the regex? For example, say I want to replace everything but string_to_replace. Instinctually I would try to extend the above by doing something like:
function replace_foo(target, string_to_replace, replacement) {
return target.replace(/^string_to_replace/,replacement);
}
This doesn't seem to work. My guess is that it thinks string_to_replace is a string literal, rather than a variable representing a string. Is it possible to create JavaScript regexes on the fly using string variables? Something like this would be great if at all possible:
function replace_foo(target, string_to_replace, replacement) {
var regex = "/^" + string_to_replace + "/";
return target.replace(regex,replacement);
}
There's new RegExp(string, flags) where flags are g or i. So
'GODzilla'.replace( new RegExp('god', 'i'), '' )
evaluates to
zilla
With string literals this is easy enough.
Not really! The example only replaces the first occurrence of string_to_replace. More commonly you want to replace all occurrences, in which case, you have to convert the string into a global (/.../g) RegExp. You can do this from a string using the new RegExp constructor:
new RegExp(string_to_replace, 'g')
The problem with this is that any regex-special characters in the string literal will behave in their special ways instead of being normal characters. You would have to backslash-escape them to fix that. Unfortunately, there's not a built-in function to do this for you, so here's one you can use:
function escapeRegExp(s) {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}
Note also that when you use a RegExp in replace(), the replacement string now has a special character too, $. This must also be escaped if you want to have a literal $ in your replacement text!
function escapeSubstitute(s) {
return s.replace(/\$/g, '$$$$');
}
(Four $s because that is itself a replacement string—argh!)
Now you can implement global string replacement with RegExp:
function replace_foo(target, string_to_replace, replacement) {
var relit= escapeRegExp(string_to_replace);
var sub= escapeSubstitute(replacement);
var re= new RegExp(relit, 'g');
return target.replace(re, sub);
}
What a pain. Luckily if all you want to do is a straight string replace with no additional parts of regex, there is a quicker way:
s.split(string_to_replace).join(replacement)
...and that's all. This is a commonly-understood idiom.
say I want to replace everything but string_to_replace
What does that mean, you want to replace all stretches of text not taking part in a match against the string? A replacement with ^ certainly doesn't this, because ^ means a start-of-string token, not a negation. ^ is only a negation in [] character groups. There are also negative lookaheads (?!...), but there are problems with that in JScript so you should generally avoid it.
You might try matching ‘everything up to’ the string, and using a function to discard any empty stretch between matching strings:
var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')')
return target.replace(re, function(match) {
return match[1]===''? match[2] : replacement+match[2];
});
Here, again, a split might be simpler:
var parts= target.split(string_to_match);
for (var i= parts.length; i-->0;)
if (parts[i]!=='')
parts[i]= replacement;
return parts.join(string_to_match);
As the others have said, use new RegExp(pattern, flags) to do this. It is worth noting that you will be passing string literals into this constructor, so every backslash will have to be escaped. If, for instance you wanted your regex to match a backslash, you would need to say new RegExp('\\\\'), whereas the regex literal would only need to be /\\/. Depending on how you intend to use this, you should be wary of passing user input to such a function without adequate preprocessing (escaping special characters, etc.) Without this, your users may get some very unexpected results.
Yes you can.
https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
function replace_foo(target, string_to_replace, replacement) {
var regex = new RegExp("^" + string_to_replace);
return target.replace(regex, replacement);
}
A really simple solution to this is this:
function replace(target, string_to_replace, replacement) {
return target.split(string_to_replace).join(replacement);
}
No need for Regexes at all
It also seems to be the fastest on modern browsers https://jsperf.com/replace-vs-split-join-vs-replaceall
I think I have very good example for highlight text in string (it finds not looking at register but highlighted using register)
function getHighlightedText(basicString, filterString) {
if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString;
return basicString.replace(new RegExp(filterString.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&'), 'gi'),
function(match)
{return "<mark>"+match+"</mark>"});
}
http://jsfiddle.net/cdbzL/1258/