Java 避免在搜索字符串中再次使用单词

Java 避免在搜索字符串中再次使用单词,java,string,replace,Java,String,Replace,我试图对照词汇表列表检查java字符串,如果它发现词汇表列表中存在一个术语,则使用html标记包装该术语。 我已经将术语表从长到短进行了排序,以避免先找到较短术语,然后再找不到较长术语的问题。。 然而,问题是,现在如果找到所有术语,就无法避免对类似术语进行第二次标记包装。例如,如果我有两个术语:“Sprint”和“Sprint0”,结果如下: <span class="term"><span class="term">Sprint</span> 0&l

我试图对照词汇表列表检查java字符串,如果它发现词汇表列表中存在一个术语,则使用html标记包装该术语。 我已经将术语表从长到短进行了排序,以避免先找到较短术语,然后再找不到较长术语的问题。。 然而,问题是,现在如果找到所有术语,就无法避免对类似术语进行第二次标记包装。例如,如果我有两个术语:“Sprint”和“Sprint0”,结果如下:

    <span class="term"><span class="term">Sprint</span> 0</span> is typically a one or two week period at the end of the Define phase. 
<br>In summary, <span class="term"><span class="term">Sprint</span> 0</span> provides an opportunity for the team to:
<ul>
Sprint 0通常是定义阶段结束时的一周或两周。

总之,Sprint 0为团队提供了一个机会:
代码如下:

私有字符串findGlossaryTerms(字符串响应,列表词汇表){
for(词汇表项:词汇表){
//检查响应是否包含术语
if(StringUtils.contains(response,item.getTerm())){
System.out.println(item.getTerm());
response=StringUtils.replace(response,item.getTerm(),“”+item.getTerm()+“”);
}           
}
System.out.println(响应);
System.out.println(“uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
返回响应;
}
如何避免这种情况?

问题是:

在替换字符串中的单词时,如果不想再次替换上一次替换的结果,则不能每次都遍历整个字符串。 您只能查看尚未替换的字符串部分

您可以检查字符串中的每个单词,看看它是否在词汇表中,而不是每次都搜索整个“response”字符串来替换它——如果在词汇表中,则用HTML代码片段替换它。如果不是,你就保持原样

方法的更新版本

private static String findGlossaryTerms(String response, List<Glossary> glossary) {
    StringBuilder builder = new StringBuilder();
    for (int offset = 0; offset < response.length(); offset++) {
        boolean match = false;
        for (Glossary item : glossary) {
            // check if the term is present at the current offset
            if (response.startsWith(item.getTerm(), offset)) {
                System.out.println(item.getTerm());
                builder.append("<span class=\"term\">").append(item.getTerm()).append("</span>");
                offset += item.getTerm().length() - 1;
                match = true;
                break;
            }
        }
        if (!match)
            builder.append(response.charAt(offset));
    }
    return builder.toString();
}
私有静态字符串findGlossaryTerms(字符串响应,列表词汇表){
StringBuilder=新的StringBuilder();
对于(int offset=0;offset
驾驶员/脚手架代码

static class Glossary {

    private String term;

    public Glossary(String term) {
        this.term = term;
    }

    public String getTerm() {
        return term;
    }
}

public static void main(String[] args) {
    List<Glossary> glossary = new ArrayList<>();
    glossary.add(new Glossary("one or two"));
    glossary.add(new Glossary("Sprint0"));
    glossary.add(new Glossary("Sprint"));

    System.out.println(findGlossaryTerms("Sprint0 is typically a one or two week period at the end of the Define phase.", glossary));
}
静态类词汇表{
私有字符串术语;
公共词汇表(字符串术语){
这个术语=术语;
}
公共字符串getTerm(){
回报期;
}
}
公共静态void main(字符串[]args){
List glossary=new ArrayList();
词汇表。添加(新词汇表(“一个或两个”);
添加(新词汇表(“Sprint0”);
添加(新词汇表(“Sprint”);
println(findGlossaryTerms(“Sprint0通常是定义阶段结束时的一到两周时间。”,术语表));
}
输出

<span class="term">Sprint0</span> is typically a <span class="term">one or two</span> week period at the end of the Define phase.
Sprint0通常是定义阶段结束时的一周或两周。

我认为您应该将对
SringUtils的调用替换为一个单词的regex find。例如,使用string的
matches
方法检查正则表达式是否正确。我已经这样做了,但仍然是一样的。它应该是这样的
string reg=“\\b”+response+“\\b”;item.getTerm().matches(reg)
对不起,我忘了提到Spring和之间有一个空格),另外,我还有一些类似于“Acceptance Criteria”的Other术语,如果我想拆分字符串,它可以在实际的词汇表列表中再次找到单词OK,我更新了答案。这一原则仍然适用:替换时不能重复相同的输入两次,因此需要跟踪您的位置。在上面的代码中,我使用了
offset
,代码在
StringBuilder结果中构建转换后的字符串。此版本不会拆分为单词,但会尝试在整个字符串中匹配词汇表术语。您仍然需要像以前一样先对术语进行排序。
<span class="term">Sprint0</span> is typically a <span class="term">one or two</span> week period at the end of the Define phase.