replace the few characters from first and last of string - javascript

replacing the first and last few characters with the * character, i am able to solve the str1 case. How can i solve the remaining one. Right now i am able to mask the last 4 characters.
how can i mask the first 3 or 4 characters. ? whats wrong in the regex pattern
var str1 = "1234567890123456";
str1 = str1.replace(/\d(?=\d{4})/g, "*");
console.log(str1)
var str2 = "123-456-789-101112"
str2 = str2.replace(/\d(?=\d{4})/g, "*");
console.log(str2) // expected ***-***-***-**1112
var str3 = "abc:def:12324-12356"
str3 = str3.replace(/\d(?=\d{4})/g, "*");
console.log(str3) // expected ***:***:*****-*2356
Right now it is masking only the four characters from last, how can i mask 4 characters from front also like
1234567890123456 => 1234********3456
123-456-789-101112 => 123-4**-***-**1112
abc:def:12324-12356 => abc:d**:*****-*2356

One option is to lookahead for non-space characters followed by 4 digits. Since you want to replace the alphabetical characters too, use a character set [a-z\d] rather than just \d:
const repl = str => console.log(str.replace(/[a-z\d](?=\S*\d{4})/g, "*"));
repl("1234567890123456");
repl("123-456-789-101112");
repl("abc:def:12324-12356");
If you want to keep the first 4 alphanumeric characters as well, then it's significantly more complicated - match and capture the first 4 characters, possibly interspersed with separators, then capture the in-between characters, then capture the last 4 digits. Use a replacer function to replace all non-separator characters in the second group with *s:
const repl = str => console.log(str.replace(
/((?:[a-z\d][-#.:]?){4})([-#:.a-z\d]+)((?:[a-z\d][-#.:]?){4})/ig,
(_, g1, g2, g3) => g1 + g2.replace(/[a-z\d]/ig, '*') + g3
));
repl("1234567890123456");
repl("123-456-789-101112");
repl("abc:def:12324-12356");
repl("test#test.com");

Related

need Regexp which leave only two dashes in a string

i have a string like d333-4444-555--5---5-
and want catch only two first dashes and get 333-4444-55555
if it will be first two and two in a row, two becomes one like:
d333--4444-555--5---5- goes 333-4444-55555
any advice or ready solvation
i started with
console.log('d-45----'.replace(/[^0-9]/g, ''))
but it's very far from what i expect
two days on the same point
Thank you
You can do multiple replacements to sanitize the string.
First replace all the 2 or more hyphens with a single hyphen as you don't know how many and where in the string you have double occurrences
Then replace all non digits except for hyphens with an empty string, and remove the hyphens at the start and at the end of the string
When you have the sanitized string, capture the first parts with 2 hyphens and in the last parts remove all hyphens
[
"d333-4444-555--5---5-",
"d333--4444-555--5---5-",
"----d333--4444-555--5---5----",
"d333--4444",
"d333-4444",
"d333"
].forEach(s => {
const res = s
.replace(/-{2,}/g, "-")
.replace(/[^\d-]+|^-|-$/g, "")
.replace(/^(\d+-\d+-)(\d[\d-]*)/, (_, g1, g2) => g1 + g2.replace(/-/g, ""))
console.log(res);
})
Another option with split and reduce:
[
"d333-4444-555--5---5-",
"d333--4444-555--5---5-",
"----d333--4444-555--5---5----",
"d333--4444",
"d333-4444",
"d333"
].forEach(s => {
const res = s
.replace(/[^\d-]+/, "")
.split(/-+/)
.filter(Boolean)
.reduce((a, c, i) => i < 2 ? a + "-" + c : a + c)
console.log(res)
})
A single regexp that finds all the undesirable dashes in your example is only possible in newer JS engines, which implement variable-length lookbehind assertions. Here it is:
const text = "d333--4444-555--5---5-";
const re = /(?<=-+.+-+.+|-)-/g;
console.log(text.replace(re, ""));
// d333-4444-55555
Match each dash that has either
two consecutive groups of hyphens somewhere before it, or
a dash directly before it
The second condition will de-dupe consecutive dashes, leaving only a single dash in the first two groups of dashes; the first condition will remove all dashes after those first two groups.
If you also want to remove any characters that are not digits or dashes, such as the leading d that Kosh asked about, then this will do it:
const text = "d333--4444-555--5---5-";
const re = /(?<=-+.+-+.+|-)-|[^\d-]/g;
console.log(text.replace(re, ""));
// 333-4444-55555
For example, Safari still does not support lookbehind assertions (haven't tried, trusting in caniuse.com), so this might not be an appropriate solution, depending on your use case. If you need to cater to such browsers, you will need to use a more complex solution; a single regexp will not be possible.
You can use a replacer callback with a counter variable:
s = 'd333---4444-55---5--5---5-'
r = s.replace(/-+/g, (count => _ => count++ < 2 ? '-' : '')(0))
console.log(r)

Regex add space in string if the word is longer than 4 characters and have numbers

I try to create a regex with 2 condition:
if word length more than 4 character
And if the word contains numbers
I need to add spaces
So like: iph12 return iph12, but iphone12 return iphone 12
I wrote regex
.replace(/\d+/gi, ' $& ').trim()
and this function return in anyway string like iphone 12. I tried to use function
.replace(/(?=[A-Z]+\d|\d+[A-Z])[A-Z\d]{,4}/i, ' $& ').trim()
but without second argument in {,4} it's not working. So is this possible?
You can use
text.replace(/\b([a-zA-Z]{4,})(\d+)\b/g, '$1 $2')
See the regex demo. Details:
\b - word boundary
([a-zA-Z]{4,}) - Group 1: four or more ASCII letters
(\d+) - Group 2: one or more digits
\b - word boundary
See the JavaScript demo:
const texts = ['iphone12', 'iph12'];
const regex = /\b([a-zA-Z]{4,})(\d+)\b/g;
for (const text of texts) {
console.log(text, '=>', text.replace(regex, '$1 $2'));
}
Output:
iphone12 => iphone 12
iph12 => iph12

Regex match all punctuations except 'D.C.'

I'm trying to write a regex that finds all punctuation marks [.!?] in order to capitalize the next word, however if the period is part of the string 'D.C.' it should be ignored, so far I have the first part working, but not sure about how to ignore 'D.C.'
const punctuationCaps = /(^|[.!?]\s+)([a-z])/g;
You can match the D.C. part and use an alternation using the 2 capturing groups that you already have.
In the replacement check for one of the groups. If it is present, concatenate them making group 2 toUpperCase(), else return the match keeping D.C. in the string.
const regex = /D\.C\.|(^|[.!?]\s+)([a-z])/g;
let s = "this it D.C. test. and? another test! it is.";
s = s.replace(regex, (m, g1, g2) => g2 ? g1 + g2.toUpperCase() : m);
console.log(s);
Use a negative lookahead:
var str = 'is D.C. a capital? i don\'t know about X.Y. stuff.';
var result = str.replace(/(^|[.!?](?<![A-Z]\.[A-Z]\.)\s+)([a-z])/g, (m, c1, c2) => { return c1 + c2.toUpperCase(); });
console.log('in: '+str);
console.log('out: '+result);
Console output:
in: is D.C. a capital? i don't know about X.Y. stuff.
out: Is D.C. a capital? I don't know about X.Y. stuff.
Explanation:
(^|[.!?]) - expect start of string, or a punctuation char
(?<![A-Z]\.[A-Z]\.) - negative lookahead: but not a sequence of upper char and dot, repeated twice
\s+ - expect one or more whitespace chars
all of the above is captured because of the parenthesis
([a-z]) - expect a lower case char, in parenthesis for second capture group

javascript regex replace 1st and 3rd space in a string

I have 2 types of strings. One of them has only 1 space and the second one has 3 spaces.
V1: "100 s" => 1 space. Number followed by a letter. Number can be 1..n digits.
V2: "2 W 10 h" => 3 spaces. Each number is followed by a letter. Again numbers can be 2..n digits.
I need to get rid of the spaces following the numbers. So the end results should be this:
V1: "100 s" -> "100s"
V2: "2 W 10 h" -> "2W 10h"
For now, I use JavaScript split function. However I need regex to replace in a more efficient way. Could you help me with that? Thanks.
const getDelayValue = delayString => {
const splitted = delayString.split(/\s+/);
if (splitted) {
if (splitted.length === 2) {
return `${splitted[0]}${splitted[1]}`;
}
return `${splitted[0]}${splitted[1]} ${splitted[2]}${splitted[3]}`;
}
return delayString;
}
Just replace numbers space string with numbers string:
str = `
100 s
2 W 10 h
`
console.log(
str.replace(/(\d+)\s+([a-z]+)/gi, "$1$2")
)
See here for the meaning of $1 in the replacement.
You can use a regex to remove the spaces
const str1 = '100 s';
const str2 = '2 W 10 h';
function removeSpace(str) {
// as # Keith pointed out, you can also use :
// return str.replace(/(\d+) +/g, '$1');
// \d is a shortcut for [0-9]
return str.replace(/([0-9]+) +/g, '$1');
}
console.log(removeSpace(str1));
console.log(removeSpace(str2));
We are matching a number followed by a space. And then replace it by the number only. To create and test your Regexp, you can use the website https://regex101.com/

Regex to extract two numbers with spaces from string

I have problem with simple rexex. I have example strings like:
Something1\sth2\n649 sth\n670 sth x
Sth1\n\something2\n42 036 sth\n42 896 sth y
I want to extract these numbers from strings. So From first example I need two groups: 649 and 670. From second example: 42 036 and 42 896. Then I will remove space.
Currently I have something like this:
\d+ ?\d+
But it is not a good solution.
You can use
\n\d+(?: \d+)?
\n - Match new line
\d+ - Match digit from 0 to 9 one or more time
(?: \d+)? - Match space followed by digit one or more time. ( ? makes it optional )
let strs = ["Something1\sth2\n649 sth\n670 sth x","Sth1\n\something2\n42 036 sth\n42 896 sth y"]
let extractNumbers = str => {
return str.match(/\n\d+(?: \d+)?/g).map(m => m.replace(/\s+/g,''))
}
strs.forEach(str=> console.log(extractNumbers(str)))
If you need to remove the spaces. Then the easiest way for you to do this would be to remove the spaces and then scrape the numbers using 2 different regex.
str.replace(/\s+/, '').match(/\\n(\d+)/g)
First you remove spaces using the \s token with a + quantifier using replace.
Then you capture the numbers using \\n(\d+).
The first part of the regex helps us make sure we are not capturing numbers that are not following a new line, using \ to escape the \ from \n.
The second part (\d+) is the actual match group.
var str1 = "Something1\sth2\n649 sth\n670 sth x";
var str2 = "Sth1\n\something2\n42 036 sth\n42 896 sth y";
var reg = /(?<=\n)(\d+)(?: (\d+))?/g;
var d;
while(d = reg.exec(str1)){
console.log(d[2] ? d[1]+d[2] : d[1]);
}
console.log("****************************");
while(d = reg.exec(str2)){
console.log(d[2] ? d[1]+d[2] : d[1]);
}

Categories