我想通过用“*”替换单词中的每个字符来审查字符串中的一些单词。基本上我想做
String s = "lorem ipsum dolor sit";
s = s.replaceAll("ipsum|sit", $0.length() number of *));
以便生成的s
等于"lorem ***** dolor ***"
。
我知道如何通过重复的replaceAll
调用来做到这一点,但我想知道,这可能与单个replaceAll
有关吗?
更新:这是研究案例研究的一部分,原因基本上是我想要使用单行程,因为它简化了生成的字节码。这不是一个严肃的网页或任何东西。
答案 0 :(得分:4)
public class Test {
public static void main(String... args) {
String s = "lorem ipsum dolor sit";
System.out.println(s.replaceAll(censorWords("ipsum", "sit"), "*"));
}
public static String censorWords(String... words) {
String re = "";
for (String w : words)
for (int i = 0; i < w.length(); i++)
re += String.format("|((?<=%s)%s(?=%s))",
w.substring(0, i), w.charAt(i), w.substring(i + 1));
return re.substring(1);
}
}
打印
lorem ***** dolor ***
生成的正则表达式并不漂亮但它可以解决问题: - )
答案 1 :(得分:4)
这是对aioobe答案的修改,使用嵌套断言而不是嵌套循环来生成断言:
public static void main(String... args) {
String s = "lorem ipsum dolor sit blah $10 bleh";
System.out.println(s.replaceAll(censorWords("ipsum", "sit", "$10"), "*"));
// prints "lorem ***** dolor *** blah *** bleh"
}
public static String censorWords(String... words) {
StringBuilder sb = new StringBuilder();
for (String w : words) {
if (sb.length() > 0) sb.append("|");
sb.append(
String.format("(?<=(?=%s).{0,%d}).",
Pattern.quote(w),
w.length()-1
)
);
}
return sb.toString();
}
一些关键点:
StringBuilder.append
在循环中而不是String +=
Pattern.quote
以逃避审查后的任何$
或\
那就是说,这不是问题的最佳解决方案。这真是一个有趣的正则表达式游戏。
我们想要用"*"
替换,所以我们必须一次匹配一个字符。问题是哪个角色。
这是一个角色,如果你回去足够长,然后你向前看,你会看到一个被删失的词。
以下是更抽象形式的正则表达式:
(?<=(?=something).{0,N})
这匹配位置,允许您返回N
个字符,您可以预测并查看something
。
答案 2 :(得分:3)
这不是审查文本的好方法。杰夫阿特伍德以这种方式发表关于审查的文章。
除非你要花很多时间在这个审查功能上,否则最终可能会审查不应该的事情。
另一个注意事项:
将Java代码转换为1行代码不一定会简化字节码。使用该逻辑,您可以将审查代码放入单个方法中,然后使用它。
答案 3 :(得分:2)
Java的replace方法不将回调作为参数;所以这并不容易。但由于亵渎过滤器主要用于网络,我认为你可以使用JavaScript。
var s = "this is some sample text to play with";
var r = s.replace(/\b(some|sample|to)\b/g, function() {
var star = "*";
var len = arguments[1].length;
while(--len)
star += "*";
return star;
});
console.log(r);//this is **** ****** text ** play with