1

This is my first post. I have problem with String in Java. I want to use regular expression. Thank you in advance for any help.

My String is:

String str = "abXYxyzXYZabXasdfggXYZ".

I want to replace all characters with "+" but not variable below:

String word = "XYZ"

So the output should be like that:

+++++++XYZ+++++++++XYZ.

I started out with:

str.replaceAll("[^" + word + "]", "+")

But I got different output like that:

++XY+++XYZ++X++++++XYZ
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
KonriMarzec
  • 45
  • 1
  • 6
  • `java.util.regex` does not support a construct that matches any text other than a certain *multicharacter* string of text. Almost all regex flavors do not support it. – Wiktor Stribiżew Nov 28 '17 at 14:15
  • Possible duplicate of [codingBat plusOut using regex](https://stackoverflow.com/questions/2628534/codingbat-plusout-using-regex) – Oneiros Nov 28 '17 at 14:37
  • That is because `[...]` in regex denotes a **set of single characters**. You can't that easily denote the inverse of whole words. So `[^XYZ]` matches every character that is not `X`, not `Y` and not `Z`, so the whole alphabet except `X, Y, Z`. It does **not** match whole words that are unequal to the word `XYZ`. – Zabuzard Nov 28 '17 at 14:55
  • Possible duplicate of [Negating a set of words via java regex](https://stackoverflow.com/questions/1333540/negating-a-set-of-words-via-java-regex) – Zabuzard Nov 28 '17 at 14:55

1 Answers1

5

Brief

This can actually be accomplished. It's an interesting approach since Java doesn't allow regex If clauses, but you can actually use a combination of lookaheads and lookbehinds within a negative lookahead to mimic a sort of If clause.


Code

See regex in use here

(?!(?:(?=XYZ)|(?<=X)(?=YZ)|(?<=XY)(?=Z))).

Replacement: +

Usage

Below code auto-generated from regex101.
See code below in use here

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

final String regex = "(?!(?:(?=XYZ)|(?<=X)(?=YZ)|(?<=XY)(?=Z))).";
final String string = "abXYxyzXYZabXasdfggXYZ";
final String subst = "+";

final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);

// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);

System.out.println("Substitution result: " + result);

Results

Input

abXYxyzXYZabXasdfggXYZ

Output

+++++++XYZ+++++++++XYZ


Explanation

  • (?!(?:(?=XYZ)|(?<=X)(?=YZ)|(?<=XY)(?=Z))) Negative lookahead ensuring what follows doesn't match
  • (?:(?=XYZ)|(?<=X)(?=YZ)|(?<=XY)(?=Z)) Match either of the following
    • (?=XYZ) Positive lookahead ensuring what follows matches XYZ literally
    • (?<=X)(?=YZ) Match the following
      • (?<=X) Positive lookbehind ensuring what precedes is X literally
      • (?=YZ) Positive lookahead ensuring what follows is YZ literally
    • (?<=XY)(?=Z) Match the following
      • (?<=XY) Positive lookbehind ensuring what precedes is XY literally
      • (?=Z) Positive lookahead ensuring what follows is Z literally
  • . Match any character
ctwheels
  • 21,901
  • 9
  • 42
  • 77