Search code examples
javaregexstringargumentsargument-passing

How to put an argument in a RegEx?


So, I am trying to use an argument in a RegEx pattern and I can't find a pattern because the argument is a simple String which is contained in the bigger string. Here is the the task itself, which I took from this codingbat.com, so everything to be clear:

THE Precondition and explanation of the task.

Given a string and a non-empty word string, return a version of the original String where all chars have been replaced by pluses ("+"), except for appearances of the word string which are preserved unchanged.

My code:

public String plusOut(String str, String word) {
  if(str.matches(".*(<word>.*<word>){1,}.*") || str.matches(".*(<word>.*<word>.*<word>){1,}.*")) {
  return str.replaceAll(".", "+");  //after finding the argument I can easily exclude it but for now I have a bigger problem in the if-condition
  } else {
  return str;
  }
}

Is there a way in Java to match an argument? The above code doesn't work for obvious reasons (<word>). How to use the argument word in the string RegEx?

UPDATE

This is the closest I got but it works only for the last char of the word String.

public String plusOut(String str, String word) 
{
  if(str.matches(".*("+ word + ".*" + word + "){1,}.*") || str.matches(".*(" + word + ".*" + word + ".*" + word + "){1,}.*") || str.matches(".*("+ word + "){1,}.*")) 
  {     
     return str.replaceAll(".(?<!" + word + ")", "+");
  } else {
     return str;
  }
}

Input/Output

plusOut("12xy34", "xy") → "+++y++" (Expected "++xy++")
plusOut("12xy34", "1") → "1+++++" (Expected "1+++++")
plusOut("12xy34xyabcxy", "xy") → "+++y+++y++++y" (Expected "++xy++xy+++xy")

It`s because of the ? in the RegEx.


Solution

  • You can't do it with only patterns, you'll have to write some code apart from the pattern. Try this:

    public static String plusOut(String input, String word) {
    
        StringBuilder builder = new StringBuilder();
        Pattern pattern = Pattern.compile(Pattern.quote(word));
        Matcher matcher = pattern.matcher(input);
        int start = 0;
    
        while(matcher.find()) {
            char[] replacement = new char[matcher.start() - start];
            Arrays.fill(replacement, '+');
            builder.append(new String(replacement)).append(word);
            start = matcher.end();
        }
        if(start < input.length()) {
            char[] replacement = new char[input.length() - start];
            Arrays.fill(replacement, '+');
            builder.append(new String(replacement));
        }
    
        return builder.toString();
    }