我收到了2个文本:
第一个:
My favorite programming language is c++.
第二个:
My favorite programming language is c.
并希望分别在这些文本中寻找c
和c++
。
为了找到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());
}
}
答案 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\+])