我正在寻找一个正则表达式来替换未被B
和A
包围的字符串中的任何Z
。
请注意,序列的内部和外部可能有许多B
s,以A
和Z
开头,但我只想替换那些外部的。{/ p>
换句话说:要求Regex进行以下JUnit测试传递需要什么?
@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);
}
真正的用例是替换CDATA部分中未包含的(X)HTML字符串的任何&
个字符。 (B
= &
,A
= <![CDATA[
和Z
= ]]>
)。
谢谢!
答案 0 :(得分:1)
您可以使用否定前瞻:
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 :(得分:1)
无限,最快捷的方式是匹配 A - Z 和 B 然后在回调中适当替换。
查找:(A[^Z]*Z)|B
替换回叫:组1匹配?第1组:&#34; x&#34;
( 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)|&");
答案 2 :(得分:0)
/(?<!A-)B(?!-Z)/
通过了测试。
@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);
}
我使用了否定前瞻(?!-Z)
并且看向后方(?<!A-)
。您可以找到here更多信息。