lynxx
lynxx

Reputation: 602

Masking middle characters in email before '@'

I want to show only the first two and the last two characters of an email like the following:

Email -  [email protected]
result - 12*****[email protected]

I am using this regex to replace the matches with * - (?<=.{2}).*(?=.{2}@).

Code snippet used:

String email = "[email protected]";
System.out.println(email.replaceAll("(?<=.{3}).*(?=.{3}@)", "*"));

// prints - 12**[email protected]
// Adds only 2 ** in the middle
// Required * for each replaced character like - 12*****[email protected]

Even though the regex matches the correct thing, It always replaces the middle part with **. But I want a * for each character. What is the problem and how to fix it?

Upvotes: 1

Views: 846

Answers (2)

Ryszard Czech
Ryszard Czech

Reputation: 18621

In Kotlin, use

val s = "[email protected]"
val p = """^([^@]{2})([^@]+)([^@]{2}@)""".toRegex()
println(s.replace(p) { 
    it.groupValues[1] + "*".repeat(it.groupValues[2].length) + it.groupValues[3]
})

See proof.

Result: 12*****[email protected].

Pattern explanation

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    [^@]{2}                  any character except: '@' (2 times)
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  (                        group and capture to \2:
--------------------------------------------------------------------------------
    [^@]+                    any character except: '@' (1 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \2
--------------------------------------------------------------------------------
  (                        group and capture to \3:
--------------------------------------------------------------------------------
    [^@]{2}                  any character except: '@' (2 times)
--------------------------------------------------------------------------------
    @                        '@'
--------------------------------------------------------------------------------
  )                        end of \3

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

You can use

.replaceAll("(\\G(?!^)|^[^@]{2})[^@](?=[^@]{2,}@)", "$1*")

See the regex demo.

  • (\G(?!^)|^[^@]{2}) - Group 1 ($1): end of the previous match or two non-@ chars at the start of the string
  • [^@] - any non-@ char
  • (?=[^@]{2,}@) - followed with 2 or more non-@ chars up to a @ char.

See the Java demo:

String email = "[email protected]";
System.out.println(email.replaceAll("(\\G(?!^)|^[^@]{2})[^@](?=[^@]{2,}@)", "$1*"));
// => 12*****[email protected]

Upvotes: 1

Related Questions