Я ищу наилучший возможный подход для поиска и замены "группы строк" в другой строке. Группа строк постоянна [около 150 строк]. Текст для поиска является динамическим [около 10000 символов, около 2000 слов)
Группа 1: {"foo", "утка", "человек" ....., "xyz") [фиксированный набор - O (150)]
Группа 2: «Меня зовут Фу. У меня есть утка» [динамический текст - O (2000)]
Входной текст: меня зовут Фу. У меня есть утка.
Ожидаемый вывод текста: меня зовут *. У меня *.
Лучший подход, который я мог придумать, это ...
1) преобразовать группу 1 в HashSet
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>");
}
}
OUTPUT
inputText: Меня зовут Фу. У меня есть утка .. не утки. Я FOO и Duckz в зоопарке. я читаю книгу и классный
Измененный текст: Меня зовут . У меня * .. не уток. Я * и duckz в зоопарке . я читаю книгу и COOL
Список запрещенных слов [duck, foo, FOO]
Список неограниченных слов [zoo, book, COOL]
Любые советы по дальнейшей оптимизации реализации приветствуются:)
Спасибо