4

I need to convert a string like

"string"

to

"*s*t*r*i*n*g*"

What's the regex pattern? Language is Java.

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
DeepL
  • 43
  • 2

4 Answers4

23

You want to match an empty string, and replace with "*". So, something like this works:

System.out.println("string".replaceAll("", "*"));
// "*s*t*r*i*n*g*"

Or better yet, since the empty string can be matched literally without regex, you can just do:

System.out.println("string".replace("", "*"));
// "*s*t*r*i*n*g*"

Why this works

It's because any instance of a string startsWith(""), and endsWith(""), and contains(""). Between any two characters in any string, there's an empty string. In fact, there are infinite number of empty strings at these locations.

(And yes, this is true for the empty string itself. That is an "empty" string contains itself!).

The regex engine and String.replace automatically advances the index when looking for the next match in these kinds of cases to prevent an infinite loop.


A "real" regex solution

There's no need for this, but it's shown here for educational purpose: something like this also works:

System.out.println("string".replaceAll(".?", "*$0"));
// "*s*t*r*i*n*g*"

This works by matching "any" character with ., and replacing it with * and that character, by backreferencing to group 0.

To add the asterisk for the last character, we allow . to be matched optionally with .?. This works because ? is greedy and will always take a character if possible, i.e. anywhere but the last character.

If the string may contain newline characters, then use Pattern.DOTALL/(?s) mode.

References

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
5

I think "" is the regex you want.

System.out.println("string".replaceAll("", "*"));

This prints *s*t*r*i*n*g*.

Sean
  • 29,130
  • 4
  • 80
  • 105
  • That's not regex ;) The `replace()` method does a char-by-char replace. Here you're replacing "nothing" by `*`. A real regex replace is done by `replaceAll()` method. – BalusC Jul 19 '10 at 16:33
  • 1
    @BalusC: I guess it's a subtle implication that regexes aren't necessary :P – BoltClock Jul 19 '10 at 16:34
  • 1
    No, it was my bad, but the empty string works as a regex as well. Edited my answer to use replaceAll instead. – Sean Jul 19 '10 at 16:36
  • 3
    Actually, `String.replace(CharSequence, CharSequence) uses `Pattern` to do the replacement. So, in effect, it is regex :p – Buhake Sindi Jul 19 '10 at 16:37
  • 1
    @TheEliteGentleman: Confirmed. Oh.My.God. Did not expect that at all. I guess I've been telling people lies in the past when I said `replace` is faster. – polygenelubricants Jul 19 '10 at 16:59
3

If this is all you're doing, I wouldn't use a regex:

public static String glitzItUp(String text) {
    return insertPeriodically(text, "*", 1);
}

Putting char into a java string for each N characters

public static String insertPeriodically(
    String text, String insert, int period) 
{
    StringBuilder builder = new StringBuilder(
        text.length() + insert.length() * (text.length()/period)+1);

    int index = 0;
    while (index <= text.length())
    {
        builder.append(insert);
        builder.append(text.substring(index,
            Math.min(index + period, text.length())));
        index += period;
    }
    return builder.toString();
}

Another benefit (besides simplicity) is that it's about ten times faster than a regex.

IDEOne | Working example

Community
  • 1
  • 1
0

Just to be a jerk, I'm going to say use J:

I've spent a school year learning Java, and self-taught myself a bit of J over the course of the summer, and if you're going to be doing this for yourself, it's probably most productive to use J simply because this whole inserting an asterisk thing is easily done with one simple verb definition using one loop.

asterisked =: 3 : 0 
 i =. 0
 running_String =. '*'
 while. i < #y do. 
    NB. #y returns tally, or number of items in y: right operand to the verb
    running_String =. running_String, (i{y) , '*'
    i =. >: i
 end.
 ]running_String
)

This is why I would use J: I know how to do this, and have only studied the language for a couple months loosely. This isn't as succinct as the whole .replaceAll() method, but you can do it yourself quite easily and edit it to your specifications later. Feel free to delete this/ troll this/ get inflamed at my suggestion of J, I really don't care: I'm not advertising it.

S_Lang
  • 87
  • 2
  • That's some really ugly code. Sorry, but good old Java code looks so much better imo. – whiskeysierra Jul 19 '10 at 20:31
  • That is what I call Java-style J. Somebody who really knows J can write that entire program in 1 line of J. Comparing Java and J is like comparing secretaries. Java is the good-looking one who can get things done, but verbosely and step-by-step. J is the one that is hard to look at and borderline ugly, but is extremely efficient and hard-working. – S_Lang Jul 23 '10 at 00:27