Java Regex: replace any B NOT between A and Z

I am looking for a regular expression that replaces any Bin a string that is not surrounded by Aand Z.
Please note that there can be many inside and outside sequences B, starting with Aand ending with Z, but I only want to replace those that are outside.

In other words: what kind of Regex is required to pass the next JUnit test?

@Test
public void testReplaceBnotBetweenAandZ() throws Exception {
    String str = "U-B-V-B-A-B-C-B-Z-W-A-B-Z-B-U";
    String repl = str.replaceAll(**#REGEX#**, "x");

    Assert.assertEquals("U-x-V-x-A-B-C-B-Z-W-A-B-Z-x-U", repl);
}

The real use case is to replace any &HTML (X) line characters that are not in the CDATA section. ( B= &, A= <![CDATA[and Z= ]]>).

Thank!

+4
source share
3

:

String repl = str.replaceAll("(?<!A[^AZ]{0,999})B(?![^AZ]*Z)", "x");
//=> U-x-V-x-A-B-C-B-Z-W-A-B-Z-x-U
+1

, - A-Z, B .

: (A[^Z]*Z)|B
: ​​ 1? 1: "x"

   ( A [^Z]* Z )                # (1)
|  B

:

Pattern p = Pattern.compile("(A[^Z]*Z)|B");
Matcher m = p.matcher(inputString);
StringBuffer sb = new StringBuffer();

while (m.find()) {
    if (m.start(1) < 0) {
        m.appendReplacement(sb, "x");
    } else {
        m.appendReplacement(sb, "$1");
    }
}

m.appendTail(sb);

:

Pattern p = Pattern.compile("(\\Q<![CDATA[\\E(?:(?!\\Q]]>\\E).)*\\Q]]>\\E)|&");
+1

/(?<!A-)B(?!-Z)/ passes the test.

 @Test
 public void testReplaceBnotBetweenAandZ() throws Exception {
    String str = "U-B-V-B-A-B-C-B-Z-W-A-B-Z-B-U";
    String repl = str.replaceAll("(?<!A-)B(?!-Z)", "x");

    Assert.assertEquals("U-x-V-x-A-B-C-B-Z-W-A-B-Z-x-U", repl);
 }

I used a negative lookahead (?!-Z)and lookbehind (?<!A-). You can find it here .

0
source

All Articles