Regex that allows only one space in the first/last name validation - javascript

I'm trying to write a regular expression to remove white spaces from just the beginning of the word, not after, and only a single space after the word.
Used RegExp:
var re = new RegExp(/^([a-zA-Z0-9]+\s?)*$/);
Test Exapmle:
1) test[space]ing - Should be allowed
2) testing - Should be allowed
3) [space]testing - Should be allowed but have to trim the space at the first
4) testing[space] - Should be allowed but have to trim the space at the last
5) testing[space][space] - should be allowed but have to trim the space at the last
6) test[space][space]ing - one space should be allowed but the remaining spaces have to be trimmed.
Any idea how this can be achieved using regex?
EDIT:
I have this,
var regExp = /^(\w+\s?)*\s*$/;
if(regExp.test($('#FirstName').val())){
$('#FirstName').val().replace(/\s+$/, '');
}else{
var elm = $('#FirstName'),
msg = 'First Name must consist of letters with no spaces';
return false;
}

Using capturing group:
var re = /^\s+|\s+$|(\s)\s+/g;
'test ing'.replace(re, '$1') // => 'test ing'
'testing'.replace(re, '$1') // => 'testing'
' testing'.replace(re, '$1') // => 'testing'
'testing '.replace(re, '$1') // => 'testing'
'testing '.replace(re, '$1') // => 'testing'
'test ing'.replace(re, '$1') // => 'test ing'

I'd probably be lazy to keep it simple and use two separate REs:
// Collapse any multiple spaces into one - handles cases 5 & 6
str.replace(/ {2,}/, ' ');
// Trim any leading space
str.replace(/^ /, '');
Or, as one statement:
var result = str.replace(/ {2,}/, ' ').replace(/^ ?/, '');

How about this:
replace(/^ | $|( ) +/, $1)?

Related

Replace every character but which is in my regex

I found this regex which validates Instagram usernames
/^(?!.*\.\.)(?!.*\.$)[^\W][\w.]{0,29}$/gim
What I'm trying to do is to replace all characters which not match my regex
let regex = new RegExp(/^(?!.*\.\.)(?!.*\.$)[^\W][\w.]{0,29}$/gim);
const filteredString = replace(text, regex, '');
I tried to add ?! at the start as a negative lookahead but no luck
Removing all the aprts that don't mach is the same as keeping the matches.
Instead of using replace you can use match and add all the matches to your filteredString, like shown below:
let text = `riegiejeyaranchen
riegie.jeyaranchen
_riegie.jeyaranchen
.riegie
riegie..jeyaranchen
riegie._.jeyaranchen
riegie.
riegie.__`;
let regex = new RegExp(/^(?!.*\.\.)(?!.*\.$)[^\W][\w.]{0,29}$/gim);
let filteredString = '';
text.match(regex).forEach(value =>
{
filteredString += value + '\r\n';
});
console.log(filteredString);
Of course the \r\n is optional (just places one on each line).
Now you get a string where non matches are removed.
Based on the regex /^(?!.*\.\.)(?!.*\.$)[^\W][\w.]{0,29}$/, the name must not have consecutive dots, no leading and trailing dots, and have max 30 word/dot chars. This code cleans up names accordingly:
[
'f',
'foobar',
'_foo.bar',
'_foo..bar',
'_foo...bar',
'_foo.bar.',
'.foo.bar',
'foo<$^*>bar',
'123456789012345678901234567890',
'1234567890123456789012345678901'
].forEach(name => {
let clean = name
.replace(/\.{2,}/g, '.') // reduce multiple dots to one dot
.replace(/^\.+/, '') // remove leading dots
.replace(/\.+$/, '') // remove trailing dots
.replace(/[^\w\.]/g, '') // remove non word/dot chars
.replace(/^(.{30}).+/, '$1'); // restrict to 30 chars
console.log(name + ' => ' + clean);
});
Output:
f => f
foobar => foobar
_foo.bar => _foo.bar
_foo..bar => _foo.bar
_foo...bar => _foo.bar
_foo.bar. => _foo.bar
.foo.bar => foo.bar
foo<$^*>bar => foobar
123456789012345678901234567890 => 123456789012345678901234567890
1234567890123456789012345678901 => 123456789012345678901234567890
Note that the original regex requires at least one char. You need to test for empty string after cleanup.

Regex replace last part of url path if condition matches?

I am basically trying to remove the last part of a URL if the URL contains the path /ice/flag/. Example:
Input:
https://test.com/plants/ice/flag/237468372912873
Desired Output:
Because the above URL has /ice/flag/ in its path, I want the last part of the URL to be replaced with redacted.
https://test.com/plants/ice/flag/redacted
However, if the URL did not have /ice/flag (ex: https://test.com/plants/not_ice/flag/237468372912873), it shouldn't be replaced.
What I tried to do is to use the answer mentioned here to change the last part of the path:
var url = 'https://test.com/plants/ice/flag/237468372912873'
url = url.replace(/\/[^\/]*$/, '/redacted')
This works in doing the replacement, but I am unsure how to modify this so that it only matches if /ice/flag is in the path. I tried putting \/ice\/flag in certain parts of the regex to change the behavior to only replace if that is in the string, but nothing has been working. Any tips from those more experienced with regex on how to do this would be greatly appreciated, thank you!
Edit: The URL can be formed in different ways, so there may be other paths before or after /ice/flag/. So all of these are possibilities:
Input:
https://test.com/plants/ice/flag/237468372912873
https://test.com/plants/extra/ice/flag/237468372912873
https://test.com/plants/ice/flag/extra/237468372912873
https://test.com/plants/ice/flag/extra/extra/237468372912873
https://test.com/plants/ice/flag/extra/237468372912873?paramOne=1&paramTwo=2#someHash
Desired Output:
https://test.com/plants/ice/flag/redacted
https://test.com/plants/extra/ice/flag/redacted
https://test.com/plants/ice/flag/extra/redacted
https://test.com/plants/ice/flag/extra/extra/redacted
https://test.com/plants/ice/flag/extra/redacted?paramOne=1&paramTwo=2#someHash
You may search for this regex:
(\/ice\/flag\/(?:[^?#]*\/)?)[^\/#?]+
and replace it with:
$1redacted
RegEx Demo
RegEx Breakup:
(: Start capture group #1
\/ice\/flag\/: Match /ice/flag/
(?:[^?#]*\/)?: Match 0 or more of any char that is not # and ? followed by a / as an optional match
): End capture group #1
[^\/#?]+ Match 1+ of any char that is not / and # and ?
Code:
var arr = [
'https://test.com/plants/ice/flag/237468372912873',
'https://test.com/plants/ice/flag/a/b/237468372912873',
'https://test.com/a/ice/flag/e/237468372912873?p=2/12#aHash',
'https://test.com/plants/not_ice/flag/237468372912873'];
var rx = /(\/ice\/flag\/(?:[^?#\n]*\/)?)[^\/#?\n]+/;
var subst = '$1redacted';
arr.forEach(el => console.log(el.replace(rx, subst)));
Here is functional code with test input strings based on your requirements:
const input = [
'https://test.com/plants/ice/flag/237468372912873',
'https://test.com/plants/extra/ice/flag/237468372912873',
'https://test.com/plants/ice/flag/extra/237468372912873',
'https://test.com/plants/ice/flag/extra/extra/237468372912873',
'https://test.com/plants/ice/flag/extra/237468372912873#someHash',
'https://test.com/plants/ice/flag/extra/237468372912873?paramOne=1&paramTwo=2#someHash',
'https://test.com/plants/not_ice/flag/237468372912873'
];
const re = /(\/ice\/flag\/([^\/#?]+\/)*)[^\/#?]+/;
input.forEach(str => {
console.log('str: ' + str + '\n => ' + str.replace(re, '$1redacted'));
});
Output:
str: https://test.com/plants/ice/flag/237468372912873
=> https://test.com/plants/ice/flag/redacted
str: https://test.com/plants/extra/ice/flag/237468372912873
=> https://test.com/plants/extra/ice/flag/redacted
str: https://test.com/plants/ice/flag/extra/237468372912873
=> https://test.com/plants/ice/flag/extra/redacted
str: https://test.com/plants/ice/flag/extra/extra/237468372912873
=> https://test.com/plants/ice/flag/extra/extra/redacted
str: https://test.com/plants/ice/flag/extra/237468372912873#someHash
=> https://test.com/plants/ice/flag/extra/redacted#someHash
str: https://test.com/plants/ice/flag/extra/237468372912873?paramOne=1&paramTwo=2#someHash
=> https://test.com/plants/ice/flag/extra/redacted?paramOne=1&paramTwo=2#someHash
str: https://test.com/plants/not_ice/flag/237468372912873
=> https://test.com/plants/not_ice/flag/237468372912873
Regex:
( - capture group start
\/ice\/flag\/ - expect /ice/flag/
([^\/#?]+\/)* - zero or more patterns of chars other than /, #, ?, followed by /
) - capture group end
[^\/#?]+ - discard anything that is not /, #, ? but expect at least one char (this will force stuff after the last /)
You can add a ternary operation condition to check if the url includes /ice/flag by url.includes('/ice/flag'), then replace url.replace(/\/[^\/]*$/, '/redacted') else return the url as it is.
function replace(url) {
return url.includes('/ice/flag') ? url.replace(/\/[^\/]*$/, '/redacted') : url;
}
console.log(replace("https://test.com/plants/ice/flag/237468372912873"))
console.log(replace("https://test.com/plants/not_ice/flag/237468372912873"));

Regex match apostrophe inside, but not around words, inside a character set

I'm counting how many times different words appear in a text using Regular Expressions in JavaScript. My problem is when I have quoted words: 'word' should be counted simply as word (without the quotes, otherwise they'll behave as two different words), while it's should be counted as a whole word.
(?<=\w)(')(?=\w)
This regex can identify apostrophes inside, but not around words. Problem is, I can't use it inside a character set such as [\w]+.
(?<=\w)(')(?=\w)|[\w]+
Will count it's a 'miracle' of nature as 7 words, instead of 5 (it, ', s becoming 3 different words). Also, the third word should be selected simply as miracle, and not as 'miracle'.
To make things even more complicated, I need to capture diacritics too, so I'm using [A-Za-zÀ-ÖØ-öø-ÿ] instead of \w.
How can I accomplish that?
1) You can simply use /[^\s]+/g regex
const str = `it's a 'miracle' of nature`;
const result = str.match(/[^\s]+/g);
console.log(result.length);
console.log(result);
2) If you are calculating total number of words in a string then you can also use split as:
const str = `it's a 'miracle' of nature`;
const result = str.split(/\s+/);
console.log(result.length);
console.log(result);
3) If you want a word without quote at the starting and at the end then you can do as:
const str = `it's a 'miracle' of nature`;
const result = str.match(/[^\s]+/g).map((s) => {
s = s[0] === "'" ? s.slice(1) : s;
s = s[s.length - 1] === "'" ? s.slice(0, -1) : s;
return s;
});
console.log(result.length);
console.log(result);
You might use an alternation with 2 capture groups, and then check for the values of those groups.
(?<!\S)'(\S+)'(?!\S)|(\S+)
(?<!\S)' Negative lookbehind, assert a whitespace boundary to the left and match '
(\S+) Capture group 1, match 1+ non whitespace chars
'(?!\S) Match ' and assert a whitespace boundary to the right
| Or
(\S+) Capture group 2, match 1+ non whitespace chars
See a regex demo.
const regex = /(?<!\S)'(\S+)'(?!\S)|(\S+)/g;
const s = "it's a 'miracle' of nature";
Array.from(s.matchAll(regex), m => {
if (m[1]) console.log(m[1])
if (m[2]) console.log(m[2])
});

Replace characters in string with *, but only characters not spaces JavaScript regex

I am wanting to mask some paragraph text out until it is hovered, so if I have a string like,
Hello World
I would want that to be, Hell* ***** how can I replace all characters with with a * after 4 characters/letters?
I know I can do all the string like this,
str.replace(/./g, '*')
but how can I limit it to after the first 4 letters?
var str = "Hello World"
var after4= str.substr(0,4)+str.substr(4).replace(/[^\s]/g, '*')
console.log(after4)
I can do this by Splitting String in Two Parts:
First Part which would remain as it is.
Second Part : I would replace all the Characters by required Character.
Concat both the Strings
let text = 'Hello World';
let str1 = text.substring(0, 4);
let str2 = text.substring(4).replace(/\S/g, '*');
let updatedStr = str1.concat(str2);
console.log(updatedStr);
/*
Single Line
let updatedStr = text.substring(0, 4) + text.substring(4).replace(/\S/g, '*');
*/
Regex Info :
\S : Any other Character other then Space (Capital 'S')
You can combine them in single line Code :
Another option could be capturing the first 4 non whitespace chars using ^(\S{4}) in group 1 and use that in the replacement.
Other non whitespace chars will be matched using an alternation followed by a single non whitspace char |\S, and those matches will be returned as *
^(\S{4})|\S
Regex demo
let str = "Hello World"
.replace(/^(\S{4})|\S/g, (_, g1) => g1 ? g1 : '*');
console.log(str);

White list in str.replace

i'm using this code to replace everyone who has website link in they name change it to nothing e.g
Username - Somewebsite.com -> Username -
For that I use this code:
name.replace(/([a-zA-Z0-9\-]*\.com)/g, '');
But I want to make it so when user is using my website adress in their name to not remove it e.g
Username - Mywebsitename.com -> Username - Mywebsitename.com
Easiest would be to just use a callback for replace() and weed out matches on a certain string
var mySite = 'Somewebsite.com';
var name = "Username - Somewebsite.com";
var result = name.replace(/([a-zA-Z0-9\-]*\.com)/g, function(what) {
return what === mySite ? what : "";
});
FIDDLE
Nearly pure regex solution:
/\s+\-\s+(?!Mywebsite\.com)([a-zA-Z0-9\-]+)\.com/i
Working example:
var regex = /\s+\-\s+(?!Mywebsite\.com)[a-zA-Z0-9\-]+\.com/i
var string = 'Username - Somewebsite.com'
var output = 'Username -'
console.log('Match:', string)
console.log('Result:', string.replace(regex, ' -'))
console.log('Correct:', (string.replace(regex, ' -') === output) === true)
console.log('') // new line
var string = 'Username - Mywebsite.com'
var output = 'Username - Mywebsite.com'
console.log('Match:', string)
console.log('Result:', string.replace(regex, ' -'))
console.log('Correct:', (string.replace(regex, ' -') === output) === true)
Regex Explanation:
/ //-> open regex
\s+ //-> match one or more spaces
\- //-> match one literal dash
\s+ //-> match one or more spaces
(?!Mywebsite\.com) //-> look ahead & assert next match is not "Mywebsite.com"
([a-zA-Z0-9\-]+) //-> match one or more lower or upper case letter, digits, & dot
\. //-> match literal dot
c //-> match c
o //-> match o
m //-> match m
/ //-> close regex
i //-> make search case insensitive
Look behind would likely have been more ideal for this, but it's not supported in JavaScript.
I hope that helps!

Categories

Resources