我想替换不在引号之间的单词。
应该如何运作:
“英雄” - 不会改变
“你是超级英雄” - 不改变
我是英雄 - 改变
你是超级英雄 - 改变
我试过
word = word.replaceAll("(?!\")(.*)hero(.*)(?!\")","$1 zero $2")
- 但它不起作用
答案 0 :(得分:1)
这个正则表达式适合你:
hero(?=(?:(?:[^\"]*\"){2})*[^\"]*$)
<强>说明:强>
这基本上意味着匹配文字文本(hero
),如果它后跟偶数个双引号,换句话说,如果它在双引号之外,则匹配所需的文本。
<强>测试强>
String str = "hero \"dont-hero\"";
String repl = str.replaceAll("hero(?=(?:(?:[^\"]*\"){2})*[^\"]*$)", "FOO");
//repl = FOO "dont-hero"
答案 1 :(得分:0)
你的问题不明确。你想处理任意数量的嵌套引号吗?如果是这样,怎么样?例如,您希望通过以下输入实现什么目标?
I hate it when people say "you are such a "hero"!"
这里的引号是“英雄”吗?或者是引号中的“你是这样的”这个短语,后跟未加引号的单词“hero”,后跟“!”在引号?
但即使是更简单的
案例"hello" said the boring old "cat", are you really a "hero"?
使用正则表达式可能无法实现,至少不能以合理的方式使其值得。
接受的答案以完全不直观的方式失败
I will be your "hero" baby! O"RLY?
为什么不用一些代码解析字符串?
我觉得以下是比使用正则表达式更好的选择:
class Main {
public static String replace(String str, String origstr, String newstr) {
StringBuilder result = new StringBuilder();
int lastIdx = 0;
boolean inquotes = false;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '"') {
if (inquotes) {
inquotes = false;
result.append(str.substring(lastIdx, i+1));
} else {
result.append(str.substring(lastIdx, i+1).replace(origstr, newstr));
inquotes = true;
}
lastIdx = i+1;
}
}
result.append(str.substring(lastIdx, str.length()).replace(origstr, newstr));
return result.toString();
}
public static void main (String[] args) throws java.lang.Exception {
System.out.println(replace("", "change", "___"));
System.out.println(replace("\"dont-change\"", "change", "___"));
System.out.println(replace("\"change", "change", "___"));
System.out.println(replace("simple: change", "change", "___"));
System.out.println(replace("simple2: \"dont-change\"", "change", "___"));
System.out.println(replace("change \"dont-change\"\"", "change", "___"));
System.out.println(replace("change \"dont-change\"", "change", "___"));
System.out.println(replace("\"dont-change\" change", "change", "___"));
}
}
答案 2 :(得分:0)
使用正则表达式的方法。
这个想法是匹配我放入捕获组的目标词之前的引号之间的所有子串。然后使用捕获组偏移量,我替换包含目标字的子字符串。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class quotyquot {
public static void main(String[] args) {
String s = "I am super hero here and now\n"
+"Superman is an incredible hero\n"
+"I am super \"hero\" here and now\n"
+"\"I am super hero here and now\"";
String t = "hero"; // target
String r = "zero"; // replacement
Integer d = r.length() - t.length();
Integer o = 0; // offset
Pattern p = Pattern.compile("\"[^\"]*\"|(" + t + ")");
Matcher m = p.matcher(s);
while (m.find()) {
if (m.group(1)!=null) {
s= s.substring(0, m.start() - o) + r + s.substring(m.end() - o);
o -= d;
}
}
System.out.println(s);
}
}
使用split的另一种方式:
String t = "hero"; // target
String r = "zero"; // replacement
int c=0; // switch
String[] pi = s.split("(?=hero|\")|(?<=hero|\")");
String result = "";
for (int i=0; i<pi.length;i++) {
if (c==0 && pi[i].equals(t))
pi[i]=r;
else if (pi[i].equals("\""))
c = 1 - c;
result += pi[i];
}
System.out.println(result);