在java中搜索和替换另一个字符串中的一组字符串的最佳方法

在java中搜索和替换另一个字符串中的一组字符串的最佳方法,java,replace,Java,Replace,我正在寻找在另一个字符串中搜索和替换一组字符串的最佳方法。这组字符串是常量[大约150个字符串]。要搜索的文本是动态的[大约10000个字符,近2000个单词] 第一组:{foo,duck,man…,xyz[固定集-O150] 第二组:我的名字是福。我有一只鸭子[动态文本-O2000] 输入文本:我的名字是福。我有一只鸭子。 预期输出文本:我的名字是*。我有一个* 我能想到的最好的方法是 1将组1转换为哈希集 2将动态文本转换为字符串[] 3循环遍历字符串[],并检查哈希集中是否存在该字

我正在寻找在另一个字符串中搜索和替换一组字符串的最佳方法。这组字符串是常量[大约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");