单词

时间:2017-10-06 19:16:34

标签: java regex

我收到了2个文本:

第一个: My favorite programming language is c++.

第二个: My favorite programming language is c.

并希望分别在这些文本中寻找cc++

为了找到c我可以写:\bc\b然后:第一个文字很糟糕!第二个是好的。我也尝试过:\bc^\+\b但不起作用。 对于fiding c++我尝试过例如:\bc\+\+\b但是第一个和第二个不起作用。请帮助。

编辑:

如果文字是I programme in c++ a lot!怎么办?

编辑:

以下是我需要完成的单元测试:

package adhoc;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

import junit.framework.TestCase;

public class FinderProgrammingTechnologyInTextTest extends TestCase{

    @Test
    public void testFind() {
        // Given:
        Set<String> setOfProgrammingLanguagesToSeek = new HashSet<>();
        setOfProgrammingLanguagesToSeek.add("java");
        setOfProgrammingLanguagesToSeek.add("perl");
        setOfProgrammingLanguagesToSeek.add("c");
        setOfProgrammingLanguagesToSeek.add("c++");

        // When:
        FinderProgrammingTechnologyInText finder = new FinderProgrammingTechnologyInText(
                setOfProgrammingLanguagesToSeek);
        Set<String> result = finder.find("java , perl! c++ and other staff");

        // Then:
        assertTrue(result.contains("java"));
        assertTrue(result.contains("perl"));
        assertFalse(result.contains("c"));
        assertTrue(result.contains("c++"));
    }

}

仅更改compile()方法的参数:

package adhoc;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class FinderProgrammingTechnologyInText {

    Set<String> setOfTechnologiesToSearch;

    public FinderProgrammingTechnologyInText(Set<String> x) {
        this.setOfTechnologiesToSearch = x;
    }

    public Set<String> find(String text) {
        Set<String> result = new HashSet<>();
        return setOfTechnologiesToSearch.stream()
                .filter(x -> Pattern
                        .compile(x)  // change only this line
                        .matcher(text).find()
                        ) 
                .collect(Collectors.toSet());       
    }
}

2 个答案:

答案 0 :(得分:3)

.compile(x)行替换为

.compile("(?<![\\w\\p{S}])" + Pattern.quote(x) + "(?![\\w\\p{S}])")

在这里,(?<![\w\p{S}])是一个负面的背后隐藏,可确保当前位置左侧没有任何单词或符号字符,而(?![\w\p{S}])否定前瞻将确保没有单词或符号字符立即位于当前位置的右侧(即,字符号和符号字符现在是您允许的“字”字符。)

查看sample regex demo for a c++ keyword at regex101.com

由于搜索字词作为文字字符序列传递给Pattern,因此它们must be escaped,这就是Pattern.quote(x)在代码中所做的事情。

答案 1 :(得分:2)

你可以在点之前找到句子中的最后一个单词。

[\w+]+(?=\.$)

https://regex101.com/r/aPYDTE/1

您的模式的问题是加号不是单词,因此单词边界\b不匹配。如果您使用点作为锚点,您将获得匹配\b(c\+\+)\.

如果您只想匹配c / c ++和其他语言,请尝试\W(c\+\+|css|c|java)\W
我添加了一个非单词\W作为边界。添加环视允许您使用完全匹配而不是使用捕获组$ 1。

(?<=\W)(c\+\+|css|c|java)(?=[^\w\+])

https://regex101.com/r/qWnOsB/4