m.spyratos
m.spyratos

Reputation: 4219

Java: Match with Regex and replace every character

I have a string, for ex:

There exists a word *random*.

random will be a random word.
How can I use a regular expression to replace every character of random with * and have this result:

There exists a word ********.

So the * replaces every character, in this case 6 characters.
Notice that I am after to replace only the word random, not the surroundings *. So far I have:

str.replaceAll("(\\*)[^.]*(\\*)", "\\*");

But it replaces *random* with *, instead of the desired ******** (total of 8).
Any help, really appreciated...

Upvotes: 3

Views: 5510

Answers (4)

Rohit Jain
Rohit Jain

Reputation: 213223

If you have just a single word like that: -

As far as current example is concerned, if you are having just a single word like that, then you can save yourself from regex, by using some String class methods: -

String str = "There exists a word *random*.";

int index1 = str.indexOf("*");
int index2 = str.indexOf("*", index1 + 1);

int length = index2 - index1 - 1;   // Get length of `random`

StringBuilder builder = new StringBuilder();

// Append part till start of "random"
builder.append(str.substring(0, index1 + 1));

// Append * of length "random".length()
for (int i = 0; i < length; i++) {
    builder.append("*");
}

// Append part after "random"
builder.append(str.substring(index2));

str = builder.toString();

If you can have multiple words like that: -

For that, here's a regex solution (This is where it starts getting a little complex): -

String str = "There exists a word *random*.";
str = str.replaceAll("(?<! ).(?!([^*]*[*][^*]*[*])*[^*]*$)", "*");
System.out.println(str);

The above pattern replaces all the characters that is not followed by string containing even numbers of * till the end, with a *.

Whichever is appropriate for you, you can use.

I'll add an explanation of the above regex: -

(?<! )       // Not preceded by a space - To avoid replacing first `*`
.            // Match any character
(?!          // Not Followed by (Following pattern matches any string containing even number of stars. Hence negative look-ahead
    [^*]*    // 0 or more Non-Star character
    [*]      // A single `star`
    [^*]*    // 0 or more Non-star character
    [*]      // A single `star`
)*           // 0 or more repetition of the previous pattern.
[^*]*$       // 0 or more non-star character till the end.     

Now the above pattern will match only those words, which are inside a pair of stars. Provided you don't have any unbalanced stars.

Upvotes: 5

Achintya Jha
Achintya Jha

Reputation: 12843

public static void main(String[] args) {
    String str = "There exists a word *random*.";
    Pattern p = Pattern.compile("(\\*)[^.]*(\\*)");

    java.util.regex.Matcher m = p.matcher(str);
    String s = "";
    if (m.find())
        s = m.group();

    int index = str.indexOf(s);
    String copy = str;
    str = str.substring(0, index);

    for (int i = index; i < index + s.length(); i++) {
        str = str + "*";
    }
    str = str + copy.substring(index + s.length(), copy.length());

    System.out.println(str);

}

Upvotes: 0

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

try

    String s = "There exists a word *random*.";
    s = s.replaceAll("\\*.+\\*", s.replaceAll(".*(\\*.+\\*).*", "$1").replaceAll(".", "*"));
    System.out.println(s);

output

There exists a word ********.

Upvotes: 0

Alex
Alex

Reputation: 25613

You can extract the word between * and do a replaceAll characters with * on it.

import java.util.regex.*;

String txt = "There exists a word *random*.";
// extract the word
Matcher m = Pattern.compile("[*](.*?)[*]").matcher(txt);
if (m.find()) {
    // group(0): *random*
    // group(1): random
    System.out.println("->> " + m.group(0));
    txt = txt.replace(m.group(0), m.group(1).replaceAll(".", "*"));
}
System.out.println("-> " + txt);

You can see it on ideone: http://ideone.com/VZ7uMT

Upvotes: 2

Related Questions