Java中的正则表达式问题
我试图在Java中为Java中的正则表达式问题,java,regex,Java,Regex,我试图在Java中为replaceAll方法创建一个正则表达式。测试字符串是abXYabcXYZ,模式是abc。我想用+替换除图案之外的任何符号。例如,字符串abXYabcXYZ和模式[^(abc)]应该返回+++++abc++,但在我的例子中,它返回ab+++abc++ public static String plusOut(String str, String pattern) { pattern= "[^("+pattern+")]" + "".toLowerCase();
replaceAll
方法创建一个正则表达式。测试字符串是abXYabcXYZ
,模式是abc
。我想用+
替换除图案之外的任何符号。例如,字符串abXYabcXYZ
和模式[^(abc)]
应该返回+++++abc++
,但在我的例子中,它返回ab+++abc++
public static String plusOut(String str, String pattern) {
pattern= "[^("+pattern+")]" + "".toLowerCase();
return str.toLowerCase().replaceAll(pattern, "+");
}
public static void main(String[] args) {
String text = "abXYabcXYZ";
String pattern = "abc";
System.out.println(plusOut(text, pattern));
}
当我尝试用+
替换模式时,没有问题-abXYabcXYZ
用模式(abc)
返回abxy+xyz
。模式(^(abc))
返回不替换的字符串
是否有其他方法将NOT(正则表达式)或分组符号作为一个单词写入?[^…]将匹配一个不属于以下任何字符的字符 因此,您的模式“[^(abc)]”表示“匹配一个不是a、b、c或左括号或右括号的字符”;事实上,这就是你测试中发生的事情 在一个简单的正则表达式中很难说“替换所有不属于字符串“abc”的字符”。你可能会做些什么来实现你想要的可能是一些令人讨厌的事情,比如
while the input string still contains "abc"
find the next occurrence of "abc"
append to the output a string containing as many "+"s as there are characters before the "abc"
append "abc" to the output string
skip, in the input string, to a position just after the "abc" found
append to the output a string containing as many "+"s as there are characters left in the input
replace all occurrences of "abc" with a single character that does not occur anywhere in the existing string
replace all other characters with "+"
replace all occurrences of the target character with "abc"
或者,如果输入字母表受到限制,您可以使用正则表达式执行以下操作
while the input string still contains "abc"
find the next occurrence of "abc"
append to the output a string containing as many "+"s as there are characters before the "abc"
append "abc" to the output string
skip, in the input string, to a position just after the "abc" found
append to the output a string containing as many "+"s as there are characters left in the input
replace all occurrences of "abc" with a single character that does not occur anywhere in the existing string
replace all other characters with "+"
replace all occurrences of the target character with "abc"
它的可读性更高,但执行起来可能不太好对regexp进行否定通常是很麻烦的。我想你可能想使用负前瞻。类似的方法可能会奏效:
String pattern = "(?<!ab).(?!abc)";
String pattern=“(?正则表达式很难实现,因为无法表示“替换不匹配模式的字符串”。您必须使用“正”模式,告诉匹配的内容而不是不匹配的内容
此外,您希望用替换字符替换每个字符,因此您必须确保模式恰好匹配一个字符。否则,您将用单个字符替换整个字符串,并返回一个较短的字符串
对于您的玩具示例,您可以使用否定的查找表和LoopBeNeDS来完成任务,但是对于具有更长或更复杂字符串的真实世界示例来说,这可能更加困难,因为您必须单独考虑字符串的每个字符以及上下文。
以下是“非abc”的模式:
[^abc]|a(?!bc)|(?<!a)b|b(?!c)|(?<!ab)c
[^abc]| a(?!bc)|(?
它由五个子模式组成,与“或”(|
)相连,每个子模式正好匹配一个字符:
[^abc]
匹配除a
、b
或c
a(?!bc)
匹配a
,如果它后面没有bc
(?匹配b
,如果前面没有a
b(?!c)
匹配b
如果后面没有c
(?匹配c
,如果前面没有ab
这样做的目的是匹配每个不在目标单词abc中的字符,再加上每个根据上下文不在单词中的字符。可以使用否定lookaheads(?!…)
和lookbehinds(?)检查上下文
您可以想象,如果目标词不止一次包含一个字符,该技术就会失败,如示例。如果后面没有x
和l
,则很难表示“匹配e
”
特别是对于动态模式,更容易进行正向搜索,然后在第二遍中替换所有不匹配的字符,正如其他人在此建议的那样。尝试在不使用正则表达式的情况下解决此问题:
String out = "";
int i;
for(i=0; i<text.length() - pattern.length() + 1; ) {
if (text.substring(i, i + pattern.length()).equals(pattern)) {
out += pattern;
i += pattern.length();
}
else {
out += "+";
i++;
}
}
for(; i<text.length(); i++) {
out += "+";
}
String out=”“;
int i;
对于(i=0;i而不是一个replaceAll,您可以尝试以下方法:
@Test
public void testString() {
final String in = "abXYabcXYabcHIH";
final String expected = "xxxxabcxxabcxxx";
String result = replaceUnwanted(in);
assertEquals(expected, result);
}
private String replaceUnwanted(final String in) {
final Pattern p = Pattern.compile("(.*?)(abc)([^a]*)");
final Matcher m = p.matcher(in);
final StringBuilder out = new StringBuilder();
while (m.find()) {
out.append(m.group(1).replaceAll(".", "x"));
out.append(m.group(2));
out.append(m.group(3).replaceAll(".", "x"));
}
return out.toString();
}
我不使用replaceAll(…)
,而是选择模式/匹配器
方法:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static String plusOut(String str, String pattern) {
StringBuilder builder = new StringBuilder();
String regex = String.format("((?:(?!%s).)++)|%s", pattern, pattern);
Matcher m = Pattern.compile(regex).matcher(str.toLowerCase());
while(m.find()) {
builder.append(m.group(1) == null ? pattern : m.group().replaceAll(".", "+"));
}
return builder.toString();
}
public static void main(String[] args) {
String text = "abXYabcXYZ";
String pattern = "abc";
System.out.println(plusOut(text, pattern));
}
}
请注意,如果字符串模式
包含正则表达式元字符,则需要使用模式.quote(…)
编辑:我没有看到一个模式/匹配器
方法已经被推荐了(虽然略有不同)是的,这就是我要做的。但是尝试用正则表达式来做这件事是一个很好的难题。