1

In Java, I want to write a regular expression to do the following:
source string: abcdefg
output string: ab***fg

source string: 123456789
output string: 12*****89

source string: a123d
output string: a1*3d

1
  • Does the amount of * in the middle need to reflect the substitution length? Commented Jan 8, 2016 at 11:01

4 Answers 4

14
(?<!^.?).(?!.?$)

The idea is:

  • (?<!) - a negative lookbehind to ensure that
  • ^.? - the start of the string is not zero or one characters away
  • . - the character that is going to be replaced
  • (?!) - a negative lookahead to ensure that
  • .?$ - the end of the string is not zero or one characters away

Replace with single *.

Sign up to request clarification or add additional context in comments.

2 Comments

cool, i leaved this path cause lookbehind does not accept variable size on pcre (default on regex101). One point for java regex engine
@GiuseppeRicupero, yep, in java you can have lookbehinds with variable length as long as they are bound by finite length. :)
3

You can use

Find: (?<=..).(?=..)
Replace: *

Details:

  • (?<=..) - a positive lookbehind that requires any two chars other than line break chars immediately to the leftht of the current location
  • . - any char other than a line break char
  • (?=..) - a positive lookahead that requires any two chars other than line break chars immediately to the right of the current location.

See the regex demo.

Here are solutions for some languages:

  • - text.replaceAll("(?<=..).(?=..)", "*")
  • - text.replace(/(?<=..).(?=..)/g, "*")
  • - re.sub(r"(?<=..).(?=..)", "*", text)
  • - Regex.Replace(text, @"(?<=..).(?=..)", "*")
  • - Regex.Replace(text, "(?<=..).(?=..)", "*")
  • - text.gsub(/(?<=..).(?=..)/, "*")
  • - gsub("(?<=..).(?=..)", "*", text, perl=TRUE)
  • - preg_replace('~(?<=..).(?=..)~', '*', $text)
  • - $text =~ s/(?<=..).(?=..)/*/g;
  • - REGEXP_REPLACE(text, '(?<=..).(?=..)', '*','g')

Comments

1

The following code use the regex (.{2})(.*)(.{2}) to do exactly what you asks (works with string from 5 chars above):

import java.util.regex.Matcher;
import java.util.regex.Pattern;

String input = "1234567890";

final Pattern hidePattern = Pattern.compile("(.{1,2})(.*)(.{1,2})");
Matcher m = hidePattern.matcher(input);
String output;

if(m.find()) {
  l = m.group(2).length();
  output = m.group(1) + new String(new char[l]).replace("\0", "*") + m.group(3);
}

System.out.println(output); // 12******90

If you need to allow less then 5 chars (till 3 below does not make sense) use:

(.{1,2})(.+)(.{1,2})

Comments

0

\A.{2}(.+).{2}\z will return you what you want. Will not work if less than 5 characters. This is language dependent. My regex is in ruby. In ruby:

\A => start of string \z => end of string

find your language equivalents.

2 Comments

What is the z flag? What flavour of regex? OP hasn't defined his language yet
\z is a metacharacter, not a flag; it matches the end of the string; so it matches only at the end of the last line in a multi-line string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.