在java中搜索和替换另一个字符串中的一组字符串的最佳方法
我正在寻找在另一个字符串中搜索和替换一组字符串的最佳方法。这组字符串是常量[大约150个字符串]。要搜索的文本是动态的[大约10000个字符,近2000个单词] 第一组:{foo,duck,man…,xyz[固定集-O150] 第二组:我的名字是福。我有一只鸭子[动态文本-O2000] 输入文本:我的名字是福。我有一只鸭子。 预期输出文本:我的名字是*。我有一个* 我能想到的最好的方法是 1将组1转换为哈希集 2将动态文本转换为字符串[] 3循环遍历字符串[],并检查哈希集中是否存在该字符串在java中搜索和替换另一个字符串中的一组字符串的最佳方法,java,replace,Java,Replace,我正在寻找在另一个字符串中搜索和替换一组字符串的最佳方法。这组字符串是常量[大约150个字符串]。要搜索的文本是动态的[大约10000个字符,近2000个单词] 第一组:{foo,duck,man…,xyz[固定集-O150] 第二组:我的名字是福。我有一只鸭子[动态文本-O2000] 输入文本:我的名字是福。我有一只鸭子。 预期输出文本:我的名字是*。我有一个* 我能想到的最好的方法是 1将组1转换为哈希集 2将动态文本转换为字符串[] 3循环遍历字符串[],并检查哈希集中是否存在该字
for(int i = 0; i < String[].length; i++){
if(HashSet.contains(String[][i]))
//Replace the string in the text
}
还有更好的选择吗
请分享你的想法
更新
这是最后一段代码,其输出用于替换另一个字符串中的字符串组
public class StringReplacementTest
{
private static final String[] restricted_words_list={"foo","duck","man","xyz"};
private static final String[] not_restricted_words_list={"zoo","book","cool"};
private static final Pattern restrictedReplacer;
private static final Pattern nonRestrictedReplacer;
private static Set<String> restrictedWords = null;
private static List<String> nonRestrictedWords = null;
static {//done once only
StringBuilder strb= new StringBuilder();
for(String str:restricted_words_list){
strb.append("\\b").append(Pattern.quote(str)).append("\\b|");
//using word break to avoid ***umptions;
}
strb.setLength(strb.length()-1);
restrictedReplacer = Pattern.compile(strb.toString(),Pattern.CASE_INSENSITIVE);
strb = new StringBuilder();
for(String str:not_restricted_words_list){
strb.append("\\b").append(Pattern.quote(str)).append("\\b|");
}
strb.setLength(strb.length()-1);
nonRestrictedReplacer = Pattern.compile(strb.toString(),Pattern.CASE_INSENSITIVE);
}
/**
* @param args
*/
public static void main(String[] args)
{
String inputText = "My name is foo. I have a duck.. not ducks. I am FOO and the duckz at the zoo. i read book and COOL";
System.out.println("inputText : " + inputText);
String modifiedText = restrictedWordCheck(inputText);
modifiedText = nonRestrictWordCheck(modifiedText);
System.out.println("Modified Text : " + modifiedText);
System.out.println("List of restricted Words" + restrictedWords);
System.out.println("List of non-restricted words" + nonRestrictedWords);
}
public static String restrictedWordCheck(String input){
Matcher m = restrictedReplacer.matcher(input);
StringBuffer strb = new StringBuffer(input.length());//ensuring capacity
while(m.find()){
if(restrictedWords==null)restrictedWords = new HashSet<String>();
restrictedWords.add(m.group()); //m.group() returns what was matched
m.appendReplacement(strb,""); //this writes out what came in between matching words
for(int i=m.start();i<m.end();i++)
strb.append("*");
}
m.appendTail(strb);
return strb.toString();
}
public static String nonRestrictWordCheck(String input){
Matcher m = nonRestrictedReplacer.matcher(input);
while(m.find()){
if(nonRestrictedWords==null)nonRestrictedWords = new ArrayList<String>();
nonRestrictedWords.add(m.group());
}
return m.replaceAll("<b>$0</b>");
}
}
输出
输入文字:我的名字是福。我有一只鸭子。不是鸭子。我是动物园里的福和鸭子。我看书,很酷
修改文本:我的名字是。我有一只*。不是鸭子。我是*和动物园里的鸭子。我看书,很酷
限制词列表[鸭子,福,福]
非限制词列表[动物园、书、酷]
欢迎提供任何进一步优化实施的建议:
谢谢使用预编译的
你可以用更复杂的东西来代替它
用标记包围单词:replacer.matcherin.replaceAll$0;$0表示整个匹配
但如果要说匹配匹配字符串的长度,则必须显式循环:
Matcher m = replacer.matcher(in);
StringBuilder strb = new StringBuilder(in.length());//ensuring capacity
while(m.find()){
m.appendReplacement(strb,"");//this writes out what came in between matching words
//m.group() returns what was matched
for(int i=m.start();i<m.end();i++)
strb.append("*");
}
m.appendTail(strb);
return strb.toString;
但是,如果您想确保最佳运行时间,您可以构建一个
要求:
using System.Text.RegularExpressions;
string group2 = "My name is foo. I have a duck";
String[] group1 = {"foo","duck","man","xyz"};
//Build the pattern
string pattern = "( "+group1[0];
for(int i = 1;i<group1.Length;i++)
{
pattern += "|" + group1[i];
}
pattern += ")";
//Apply it
Regex a = new Regex(pattern);
group2 = a.Replace(group2, "what you want to leave behind instead of any of the words");
每个单词是用相同的字符串替换,还是有不同的替换?请提供输入文本、目标匹配和预期输出的示例。您必须使用组1的字符串创建一个正则表达式,然后将其应用于Replaceregularexpression、stringToReplacedFor。这将是一个巨大的链,但没有循环我能想到的唯一一件事。你为什么不想循环呢?请注意,在某些情况下,循环是不可避免的,无论你是否显式编码-即使是正则表达式也会在深层使用循环@Louis:是的,它们被相同的字符串替换。@rachet:谢谢你的方法。你能分享一下你对性能的看法吗如果我的arr有150个字符串,则上述方法的性能。文本有2000个字符串。是否可以用类似的aproach替换动态内容的字符串???输入文本:我的名字是foo。我有一只鸭子。预期输出文本:我的名字是foo。我有一只鸭子@rachet:谢谢你的帮助详细的代码。这有助于我进一步分析实现如何扩展上述不区分大小写的匹配方法?将Pattern.case_insensitive作为第二个参数添加到
using System.Text.RegularExpressions;
string group2 = "My name is foo. I have a duck";
String[] group1 = {"foo","duck","man","xyz"};
//Build the pattern
string pattern = "( "+group1[0];
for(int i = 1;i<group1.Length;i++)
{
pattern += "|" + group1[i];
}
pattern += ")";
//Apply it
Regex a = new Regex(pattern);
group2 = a.Replace(group2, "what you want to leave behind instead of any of the words");