I have a string which could contain several different values, among them are.
EDITED for clarity:
var test could equal FW21002-185 or FW21002-181-0001 or abcdefg or 245-453-654 or FW21002-181-00012
I would like to remove all characters after and including the last - only if that string contains four characters after the last dash. So in the above strings examples, the only one that should be changed is the second one to "FW21002-181" All others would remain as they are.
How would I do this in JavaScript. Regex is ok as well. Thanks.
A regex to do this would be
var chopped = test.replace(/-[^-]{4,}$/, '-');
(assuming you want that "-" at the end). (Oh also this is intended to match 4 or more trailing characters - if you want exactly four, just get rid of the comma in {4,}.)
No regex required:
var str = ...,
pos = str.lastIndexOf('-');
if (pos > -1 && pos == str.length - 5)
str = str.substring(0, pos);
If you don't want to use a regex:
function removeLongSuffix(var str)
{
var tokens = str.split('-'),
last = tokens[tokens.length-1];
if (last.length > 3)
{
return tokens.slice(0,-1).join('-');
}
return str;
}
Related
I've been struggling getting my regex function to work as intended. My goal is to iterate endlessly over a string (until no match is found) and remove all duplicate, adjacent characters. Aside from checking if 2 characters (adjacent of each other) are equal, the regex should only remove the match when one of the pair is uppercase.
e.g. the regex should only remove 'Xx' or 'xX'.
My current regex only removes matches where a lowercase character is followed by any uppercase character.
(.)(([a-z]{0})+[A-Z])
How can I implement looking for the same adjacent character and the pattern of looking for an uppercase character followed by an equal lowercase character?
You'd either have to list out all possible combinations, eg
aA|Aa|bB|Bb...
Or implement it more programatically, without regex:
let str = 'fooaBbAfoo';
outer:
while (true) {
for (let i = 0; i < str.length - 1; i++) {
const thisChar = str[i];
const nextChar = str[i + 1];
if (/[a-z]/i.test(thisChar) && thisChar.toUpperCase() === nextChar.toUpperCase() && thisChar !== nextChar) {
str = str.slice(0, i) + str.slice(i + 2);
continue outer;
}
}
break;
}
console.log(str);
Looking for the same adjacent character: /(.)\1/
Looking for an uppercase character followed by an equal lowercase character isn't possible in JavaScript since it doesn't support inline modifiers. If they were regex should be: /(.)(?!\1)(?i:\1)/, so it matches both 'xX' or 'Xx'
I'm aiming to remove a succeeding occurrence of 2 particular characters from a string: the dot and the negative sign. let's say we have -123-456.78.9.0-12, I should be getting -123456.789012 afterwards. can it be done via regex replace?
If I may add, my complete goal is to just allow numbers, negative sign, and dot, with the negative sign only being allowed either as the first character or not present at all.
thanks so much
You can do this in 3 replace calls:
function repl(n) {
return n.replace(/[^\d.-]+/g, '') // remove all non-digits except - and .
.replace(/^([^.]*\.)|\./g, '$1') // remove all dots except first one
.replace(/(?!^)-/g, '') // remove all hyphens except first one
}
console.log(repl('-123-456.78.9.0-12'))
//=> "-123456.789012"
console.log(repl('-123-#456.78.9.0-12-abc-foo'))
//=> "-123456.789012"
console.log(repl('-1234'))
//=> "-1234"
console.log(repl('#-123-#456.78.9.0-12-abc-foo'))
//=> "-123456.789012"
Here:
First replace method is replacing every non-digit character except - and .
Second replace method is replacing every dot except the first one.
Third replace method is replacing every hyphen except the first hyphen.
If you want to avoid using RegExps, you can do something like this:
let str = '-123-456.78.9.0-12';
let output = '';
if (str[0] == '-') output += '-';
let periodIdx = str.indexOf('.');
for (let idx = 0; idx < str.length; idx += 1) {
let char = str.charCodeAt(idx);
if (char > 47 && char < 58) output += str[idx];
if (idx == periodIdx) output += '.';
}
console.log(output);
If I may add, my complete goal is to just allow numbers, negative sign, and dot, with the negative sign only being allowed either as the first character or not present at all.
^-?[^.-]*\.?[^.-]*$
I did find this function in jQuery that add a dash after very four numbers, but I would like to add a dash to a number entered by the user with the follow format:
1234-1234556-123-1
but I could manage to get it, could you please help me, this is the jQuery function that formats the follow: 1234-1234-1234-1
$('.creditCardText').keyup(function() {
var foo = $(this).val().split("-").join(""); // remove hyphens
if ((foo.length > 0) && (foo.length < 14)) {
foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
}
$(this).val(foo);
});
You need to use parenthetical matching groups. Put the pattern in parenthesis. This will return an array with the whole match, followed by the parenthetical matches, followed by some match info. So, you have to slice out array elements 1-4, and then join them with dashes. Because some of the matches may be empty, you can clean up with another replace that removes trailing dashes:
Edit: You could also remove all non-numeric characters, instead of just hyphens. (See second line)
$('.creditCardText').keyup(function() {
var foo = $(this).val().replace(/\D/g, ""); // remove non-numerics
if ((foo.length > 0) && (foo.length < 16)) {
foo = foo.match(new RegExp('(\\d{1,4})(\\d{0,7})(\\d{0,3})(\\d?)')).slice(1,5).join("-").replace(/\-+$/, '');
}
$(this).val(foo);
});
Demo: https://jsfiddle.net/oohfksjd/
It is more RegExp issue, not JavaScript.
RegExp('(.{1,4})(.{1,7})(.{1,3})(.{1,1})', 'g')
code for detecting repeating letter in a string.
var str="paraven4sr";
var hasDuplicates = (/([a-zA-Z])\1+$/).test(str)
alert("repeating string "+hasDuplicates);
I am getting "false" as output for the above string "paraven4sr". But this code works correctly for the strings like "paraaven4sr". i mean if the character repeated consecutively, code gives output as "TRUE". how to rewrite this code so that i ll get output as "TRUE" when the character repeats in a string
JSFIDDLE
var str="paraven4sr";
var hasDuplicates = (/([a-zA-Z]).*?\1/).test(str)
alert("repeating string "+hasDuplicates);
The regular expression /([a-zA-Z])\1+$/ is looking for:
([a-zA-Z]]) - A letter which it captures in the first group; then
\1+ - immediately following it one or more copies of that letter; then
$ - the end of the string.
Changing it to /([a-zA-Z]).*?\1/ instead searches for:
([a-zA-Z]) - A letter which it captures in the first group; then
.*? - zero or more characters (the ? denotes as few as possible); until
\1 - it finds a repeat of the first matched character.
If you have a requirement that the second match must be at the end-of-the-string then you can add $ to the end of the regular expression but from your text description of what you wanted then this did not seem to be necessary.
Try this:
var str = "paraven4sr";
function checkDuplicate(str){
for(var i = 0; i < str.length; i++){
var re = new RegExp("[^"+ str[i] +"]","g");
if(str.replace(re, "").length >= 2){
return true;
}
}
return false;
}
alert(checkDuplicate(str));
Here is jsfiddle
To just test duplicate alphanumeric character (including underscore _):
console.log(/(\w)\1+/.test('aab'));
Something like this?
String.prototype.count=function(s1) {
return (this.length - this.replace(new RegExp(s1,"g"), '').length) / s1.length;
}
"aab".count("a") > 1
EDIT: Sorry, just read that you are not searching for a function to find whether a letter is found more than once but to find whether a letter is a duplicate. Anyway, I leave this function here, maybe it can help. Sorry ;)
I made this helper function to find single words, that are not part of bigger expressions
it works fine on any word that is NOT first or last in a sentence, why is that?
is there a way to add "" to regexp?
String.prototype.findWord = function(word) {
var startsWith = /[\[\]\.,-\/#!$%\^&\*;:{}=\-_~()\s]/ ;
var endsWith = /[^A-Za-z0-9]/ ;
var wordIndex = this.indexOf(word);
if (startsWith.test(this.charAt(wordIndex - 1)) &&
endsWith.test(this.charAt(wordIndex + word.length))) {
return wordIndex;
}
else {return -1;}
}
Also, any improvement suggestions for the function itself are welcome!
UPDATE: example: I want to find the word able in a string, I waht it to work in cases like [able] able, #able1 etc.. but not in cases that it is part of another word like disable, enable etc
A different version:
String.prototype.findWord = function(word) {
return this.search(new RegExp("\\b"+word+"\\b"));
}
Your if will only evaluate to true if endsWith matches after the word. But the last word of a sentence ends with a full stop, which won't match your alphanumeric expression.
Did you try word boundary -- \b?
There is also \w which match one word character ([a-zA-Z_]) -- this could help you too (depends on your word definition).
See RegExp docs for more details.
If you want your endsWith regexp also matches the empty string, you just need to append |^$ to it:
var endsWith = /[^A-Za-z0-9]|^$/ ;
Anyway, you can easily check if it is the beginning of the text with if (wordIndex == 0), and if it is the end with if (wordIndex + word.length == this.length).
It is also possible to eliminate this issue by operating on a copy of the input string, surrounded with non-alphanumerical characters. For example:
var s = "#" + this + "#";
var wordIndex = this.indexOf(word) - 1;
But I'm afraid there is another problems with your function:
it would never match "able" in a string like "disable able enable" since the call to indexOf would return 3, then startsWith.test(wordIndex) would return false and the function would exit with -1 without searching further.
So you could try:
String.prototype.findWord = function (word) {
var startsWith = "[\\[\\]\\.,-\\/#!$%\\^&\*;:{}=\\-_~()\\s]";
var endsWith = "[^A-Za-z0-9]";
var wordIndex = ("#"+this+"#").search(new RegExp(startsWith + word + endsWith)) - 1;
if (wordIndex == -1) { return -1; }
return wordIndex;
}