Replace only if the containing string length is greater than X - javascript

I've a regex that will only match one character of the strings. I want to test the lentgh of its containing string and if it was greater than 4 then make the replacement. For example, the regex is /\d/. I want to use the functional form of replace to match 12345 but not 1234.
Something like:
text.replace(regex, function(match) {
if (STRING.length > 4)
return replacement
else
return match;
});
Note:
/\d/ is just an example. I didn't mention the real regex to focus on my real question, illustrated above.

Or if you want to do it that way:
function replaceWithMinLength (str, minLength) {
str.replace(/\w+/, function(match) {
if (match.length > minLength) {
return match;
} else {
return str;
}
});
}

You're putting the horse before the cart. You would be better off:
if(string.length > 4) {
string.replace('needle','replacement');
}

So by “containing string”, you mean like the same sequence of digits? Match them all at once:
text.replace(/\d{5,}/g, function(string) {
return string.replace(/\d/g, function(match) {
return replacement;
});
});
For example. The \d{5,} can easily be adapted to any type of string-thing.

Related

Regular expression to count characters after coma

How can I build a regular expression that will replace each comma with a '.' decimal point if there are more than 3 or less than 3 digits.
that is 4,444 is correct and stay like that but 3,33 will be 3.33 or 4,4444 will be 4.444
similarly it can be like this as well 1,234,45,6789, and it should become 1,234.45.6789
function commaToDot(number) {
let regex = /^\d{1,3}(?:\,\d{3})*((?:,\d+)+)*?$/;
let matches = number.match(regex);
if (matches[1]) {
number = number.replace(matches[1], matches[1].replace(/,/g, '.'))
}
return number;
}
console.log(commaToDot('4,4444'));
console.log(commaToDot('5,555'));
console.log(commaToDot('3,33'));
console.log(commaToDot('1,234,45,6789'));
console.log(commaToDot('1,234,45,678,9'));
console.log(commaToDot('5,5,5,5,5'));
This will match everything after the numbers stop being part of the \d{1,3},\d{3} pattern, and replace their commas with dots.
From what I gather, this is what you are looking for.
Edit
After leaving my comment above to check validity of "1,333.22,333", I've had to re-write the regex slightly:
function commaToDot(number) {
let regex = /(?!,\d{3},)(,\d{0,2})|(,\d{4,})/g,
matches = number.match(regex);
if (matches) {
matches.forEach((match) => {
number = number.replace(match, match.replace(/,/g, '.'));
});
}
return number
}
console.log(commaToDot('1,234,45,678,9'));
console.log(commaToDot('4,4444'));
console.log(commaToDot('5,555'));
console.log(commaToDot('3,33'));
console.log(commaToDot('1,234,45,6789'));
console.log(commaToDot('5,5,5,5,5'));
console.log(commaToDot('12,345,678,90'));
This should now do what you would like it to do.
With RegExp.test() function and specific regex patterns:
var commaToDot = function(str){
if (/^-?\d+[,\d]+\d+$/.test(str) && /\d+,(\d{1,2}|\d{4,})\b/.test(str)){
var parts = str.split(',');
return parts.length > 2? parts[0] +','+ parts.slice(1).join('.') : parts.join('.');
} else {
return str;
}
};
console.log(commaToDot('4,4444'));
console.log(commaToDot('5,555'));
console.log(commaToDot('3,33'));
console.log(commaToDot('1,234,45,6789'));

Replace matches with regex

I am trying to replace matches of text between dollar signs.
So the text $match$ inside Some text and $some text that matches$. should be replaced.
I have tried
text.replace(/\$.*?\$/g, function (match) {
return '_' + match + '_';
}
This works. The problem is that I want to do evaluate the match inside this function, but sometimes the evaluation didn't work, and in these cases I just want to return the original match. So it is something like
text.replace(/\$.*?\$/g, function (match) {
try {
return evaluate(match);
} catch (e) {
return match;
}
}
But with my current regex, the match contains the dollar signs from the original text. I want it to omit the dollar signs, but if the evaluation fails, then I want the original dollar signs back.
What I could do is
text.replace(/\$.*?\$/g, function (match) {
try {
return evaluate(match.replace(/\$/g, ''));
} catch (e) {
return match;
}
}
but isn't it possible in a more elegant way?
Something like this might do:
const evaluate = function(str) {
if (str && str.startsWith("t")) {return str.toUpperCase();}
throw "Gotta hava a 'T'";
};
"ab$test$cd $something$ that is $tricky$.".replace(/\$([^$]*)\$/g;, function(str, match) {
try {
return evaluate(match);
} catch(e) {
return str;
}
}); //=> "abTESTcd $something$ that is TRICKY."
But I agree with the comment that you might be better returning a different signal (undefined? null?) from evaluate rather than throwing for this case. And then the function body could simply be something like:
return evaluate(match) || str;
The point is the capturing group in the regex: /\$([^$]*)\$/g;, which becomes a parameter to the replacement function.

JavaScript: RegEx - Do not return match1 match2 etc

I'm trying to adopt this regex for my needs:
(?:^|\s)(?:https?:\/\/)?(?:\w+(?=\.).)?(?<name>.*).(?<tld>(?<=\.)\w+)
Demo:
https://regex101.com/r/lI2lB4/2
I would like to return a match for all entries like:
www.example.com
example.com
http://example.com
http://www.example.com
but not for
example.
http://www.example
www.example
Now the regex shown above is working fine, but it returns different matches (Match 1, Match 2, ...) - but would like to get only one result: Matching or not matching.
As a result I would like to use
regExDomain.test($regExDomain.test(input.val()))
{
console.log('valid');
}
else
{
console.log('invalid');
}
The problem is: The regEx above seems always to return "valid".
Any ideas how to do that?
The test() function of Regex class should be enough to validate whether the input matches the pattern.
You could do something like this:
var pattern = /^(http[s]?:\/\/)?(www\.)?([^\.]+)\.[^\.]{2,3}$/
var regex = new RegExp(pattern);
for(var i=1; i<=3; i++) {
if ( regex.test( $("#text"+i).text() ) )
$("#isMatch"+i).html("MATCHES");
else
$("#isMatch"+i).html("DOESN'T MATCH");
}
jsfiddle example: http://jsfiddle.net/jyu16m89/1/
The above example will return false for the extended domains (e.g. ".digital" or ".menu" ). If you want to include it in your pattern, replace {2,3} by +
If you want to include subdomains/folders in your pattern (e.g. returning true for entries like http://stackoverflow.com/questions/), remove the dollar sign (this not limiting the string to end there).
You have a grouped regex so it will return match[n] where n is the number of groups that matched. If nothing matches then you'll get null as a result:
function isUrl(myString) {
var match = myString.match('/(?:^|\s)(?:https?:\/\/)?(?:\w+(?=\.).)?(?<name>.*).(?<tld>(?<=\.)\w+)/');
if(match !== null) {
return true;
}
return false;
}

Split string in JavaScript using regex with zero width lookbehind

I know JavaScript regular expressions have native lookaheads but not lookbehinds.
I want to split a string at points either beginning with any member of one set of characters or ending with any member of another set of characters.
Split before ເ, ແ, ໂ, ໃ, ໄ. Split after ະ.
In: ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ
Out: ເລື້ອຍໆມະ ຫັດສະ ຈັນ ເອກອັກຄະ ລັດຖະ ທູດ
I can achieve the "split before" part using zero-width lookahead:
'ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ'.split(/(?=[ໃໄໂເແ])/)
["ເລື້ອຍໆມະຫັດສະຈັນ", "ເອກອັກຄະລັດຖະທູດ"]
But I can't think of a general approach to simulating zero-width lookbehind
I'm splitting strings of arbitrary Unicode text so don't want to substitute in special markers in a first pass, since I can't guarantee the absence of any string from my input.
Instead of spliting, you may consider using the match() method.
var s = 'ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ',
r = s.match(/(?:(?!ະ).)+?(?:ະ|(?=[ໃໄໂເແ]|$))/g);
console.log(r); //=> [ 'ເລື້ອຍໆມະ', 'ຫັດສະ', 'ຈັນ', 'ເອກອັກຄະ', 'ລັດຖະ', 'ທູດ' ]
You could try matching rather than splitting,
> var re = /((?:(?!ະ).)+(?:ະ|$))/g;
undefined
> var str = "ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ"
undefined
> var m;
undefined
> while ((m = re.exec(str)) != null) {
... console.log(m[1]);
... }
ເລື້ອຍໆມະ
ຫັດສະ
ຈັນເອກອັກຄະ
ລັດຖະ
ທູດ
Then again split the elements in the array using lookahead.
If you use parentheses in the delimited regex, the captured text is included in the returned array. So you can just split on /(ະ)/ and then concatenate each of the odd members of the resulting array to the preceding even member. Example:
"ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູ".split(/(ະ)/).reduce(function(arr,str,index) {
if (index%2 == 0) {
arr.push(str);
} else {
arr[arr.length-1] += str
};
return arr;
},[])
Result: ["ເລື້ອຍໆມະ", "ຫັດສະ", "ຈັນເອກອັກຄະ", "ລັດຖະ", "ທູ"]
You can do another pass to split on the lookahead:
"ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູ".split(/(ະ)/).reduce(function(arr,str,index) {
if (index%2 == 0) {
arr.push(str);
} else {
arr[arr.length-1] += str
};
return arr;
},[]).reduce(function(arr,str){return arr.concat(str.split(/(?=[ໃໄໂເແ])/));},[]);
Result: ["ເລື້ອຍໆມະ", "ຫັດສະ", "ຈັນ", "ເອກອັກຄະ", "ລັດຖະ", "ທູ"]

javascript regex does not work for sentence string

I am writing a function which takes string as an argument. Then if the string begins with capital letter then return true otherwise return false. But my current function only works for one word string which I want it to work for both one word and a whole sentence. How can I improve my code to achieve this? Secondly, it should not work when numbers are passed inside sentence. How can I do this?
Here is my code
function takeString (str) {
var regex = /^[A-Za-z]+$/;
if (str.match(regex)) {
if (str.charAt(0) === str.toUpperCase().charAt(0)) {
alert('true');
return true;
} else {
alert('false');
return false;
}
} else {
alert('Only letters please.');
}
}
takeString('This is'); // shows Only letters please which is wrong. this should work
takeString('String); // returns true which right
takeString('string'); // returns false which is right
takeString('This is 12312321'); // shows only letters please which is right bcoz it has digits
takeString('12312312'); // show Only letters please which is right.
​
Spaces aren't letters. You have to add them into your character set:
> 'This is a string'.match(/^[A-Za-z]+$/);
null
> 'This is a string'.match(/^[A-Za-z\s]+$/);
["This is a string"]
\s matches all whitespace, so if you don't want to match tabs, replace \s with a space.
Here's a slightly more condensed version of your code:
function takeString(str) {
return str.match(/^[A-Z][A-Za-z ]*$/);
}
along with the regex advice given by Blender, you'll want to also do the following (in order to satisfy the need to check each word ... assuming words are space or tab separated only:
use the split function to break the string into words ( var mywords = str.split(/\s+/) )
iterate over mywords array returned by split, checking each array element against the regex
return an error if the regex doesnt match
return success if you match every word
takeString (str) {
var mywords = str.split(/\s+/);
for (i = 0; i < mywords.length; i++) {
if (str.match(/^[A-Z][A-Za-z]*$/) != true) {
return false;
}
}
return true;
}
(someone needs to check my js ... )

Categories

Resources