如何在java中查找字符串中的整个单词
我有一个字符串,我必须分析不同的关键字。 例如,我有以下字符串: “我会到森林来接你” 我的关键词是 “123woods” “伍兹” 无论何时何地有比赛,我都要报告。还应考虑多次发生。然而,对于这一个,我应该得到一个匹配只在123woods,而不是在woods。这消除了使用String.contains()方法。此外,我应该能够有一个列表/一组关键字,同时检查它们的出现情况。在这个例子中,如果我有'123woods'和'come',我应该会出现两次。方法在大文本上的执行应该有点快如何在java中查找字符串中的整个单词,java,string,pattern-matching,stringtokenizer,Java,String,Pattern Matching,Stringtokenizer,我有一个字符串,我必须分析不同的关键字。 例如,我有以下字符串: “我会到森林来接你” 我的关键词是 “123woods” “伍兹” 无论何时何地有比赛,我都要报告。还应考虑多次发生。然而,对于这一个,我应该得到一个匹配只在123woods,而不是在woods。这消除了使用String.contains()方法。此外,我应该能够有一个列表/一组关键字,同时检查它们的出现情况。在这个例子中,如果我有'123woods'和'come',我应该会出现两次。方法在大文本上的执行应该有点快 我的想法是使用
我的想法是使用StringTokenizer,但我不确定它是否会表现良好。有什么建议吗?您可以使用正则表达式。
使用Matcher和Pattern方法来获得所需的输出类似于
Arrays.asList(String.split(“”)).contains(“xx”)
请参见和。以下示例基于您的评论。它使用一个关键字列表,将使用单词边界在给定字符串中搜索这些关键字。它使用ApacheCommonsLang中的StringUtils构建正则表达式并打印匹配的组
String text = "I will come and meet you at the woods 123woods and all the woods";
List<String> tokens = new ArrayList<String>();
tokens.add("123woods");
tokens.add("woods");
String patternString = "\\b(" + StringUtils.join(tokens, "|") + ")\\b";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
String text=“我会来树林和所有的树林与你见面”;
List tokens=new ArrayList();
代币。添加(“123woods”);
代币。添加(“伍兹”);
String patternString=“\\b(“+StringUtils.join(标记“|”)+”\\b”;
Pattern=Pattern.compile(patternString);
Matcher Matcher=pattern.Matcher(文本);
while(matcher.find()){
系统输出println(匹配器组(1));
}
如果您希望获得更高的性能,您可以看看:Java中的高性能模式匹配算法。您还可以使用带有\b标志(整个单词边界)的正则表达式匹配。尝试使用正则表达式进行匹配。与“\b123wood\b”匹配,\b是一个断字。使用正则表达式+单词边界,其他人回答
"I will come and meet you at the 123woods".matches(".*\\b123woods\\b.*");
这是真的
"I will come and meet you at the 123woods".matches(".*\\bwoods\\b.*");
将是错误的。希望这对您有用:
String string = "I will come and meet you at the 123woods";
String keyword = "123woods";
Boolean found = Arrays.asList(string.split(" ")).contains(keyword);
if(found){
System.out.println("Keyword matched the string");
}
一种更简单的方法是使用split() 这是一种更简单、不太优雅的方法,可以在不使用令牌的情况下执行相同的操作。要匹配“123woods”而不是“woods”,请在正则表达式中使用原子分组。 需要注意的是,在单独匹配“123woods”的字符串中,它将匹配第一个“123woods”并退出,而不是进一步搜索同一字符串
\b(?>123woods|woods)\b
它将123woods作为主要搜索进行搜索,一旦匹配,它将退出搜索。在Android中找到了一种匹配精确单词的方法
String full = "Hello World. How are you ?";
String one = "Hell";
String two = "Hello";
String three = "are";
String four = "ar";
boolean is1 = isContainExactWord(full, one);
boolean is2 = isContainExactWord(full, two);
boolean is3 = isContainExactWord(full, three);
boolean is4 = isContainExactWord(full, four);
Log.i("Contains Result", is1+"-"+is2+"-"+is3+"-"+is4);
Result: false-true-true-false
匹配字的函数:
private boolean isContainExactWord(String fullString, String partWord){
String pattern = "\\b"+partWord+"\\b";
Pattern p=Pattern.compile(pattern);
Matcher m=p.matcher(fullString);
return m.find();
}
完成回顾最初的问题,我们需要在给定的句子中找到一些给定的关键字,计算出现的次数,并了解出现的位置。我不太明白“where”是什么意思(它是句子中的索引吗?),所以我会传递那个。。。我仍在学习java,一步一个脚印,所以我会在适当的时候完成这一步:-) 必须注意的是,常见的句子(如原问题中的句子)可能有重复的关键字,因此搜索不能只询问给定的关键字“是否存在”,如果确实存在,则将其计为1。可以有多个相同的。例如:
// Base sentence (added punctuation, to make it more interesting):
String sentence = "Say that 123 of us will come by and meet you, "
+ "say, at the woods of 123woods.";
// Split it (punctuation taken in consideration, as well):
java.util.List<String> strings =
java.util.Arrays.asList(sentence.split(" |,|\\."));
// My keywords:
java.util.ArrayList<String> keywords = new java.util.ArrayList<>();
keywords.add("123woods");
keywords.add("come");
keywords.add("you");
keywords.add("say");
结果是:
发现:说发现:来
发现:你
发现:说
发现:123woods
在句子中:假设我们中的123人会经过这里,在123woods的树林里遇见你。
计数:5
解决方案似乎早已被接受,但解决方案可以改进,因此如果有人有类似问题: 这是多模式搜索算法的经典应用程序 Java模式搜索(使用
Matcher.find
)不适合这样做。只搜索一个关键字在java中是优化的,搜索or表达式使用正则表达式非确定性自动机,该自动机对不匹配进行回溯。在更糟糕的情况下,文本的每个字符将被处理l次(其中l是模式长度的总和)
单模式搜索更好,但也不合格。你必须开始搜索每一个关键词模式。在更糟糕的情况下,文本的每个字符将被处理p次,其中p是模式数
多模式搜索将只处理文本的每个字符一次。适合这种搜索的算法可能是Aho Corasick、Wu Manber或Set-Backward Oracle匹配。这些可以在像或这样的库中找到
//StringSearch算法示例
ahocarasick stringSearch=新ahocarasick(asList(“123woods”,“woods”));
CharProvider text=new StringCharProvider(“我会在树林123和所有树林与您见面”,0);
StringFinder=stringSearch.createFinder(文本);
List all=finder.findAll();
您确定逻辑没有缺陷吗?如果你有关键词——123个和123个。那么在文本单词123中,哪些单词是匹配的?无。我只需要精确的单词匹配。如果我有一个ArrayList,我想用一个模式来构建它呢?似乎我必须使用可靠的旧StringBuilder?@baba-你可以这样做,或者你可以遍历列表。我不确定哪种方法更有效,如果性能是一个问题,您可能想尝试这两种方法。我个人更喜欢遍历列表。在我的答案中添加了这个选项。@baba:现在我开始明白了。我根据您的评论更新了我的答案。使用Java 8,不再需要StringUtils
String
有静态的join()
方法可以完成这项工作。虽然理解和编写起来更简单,但这并不是我所问问题的答案。我有两个或三个,或者可能是无限数量的“匹配”关键字,我需要得到那些在“文本”中找到的。当然,你可以循环我的“m”
// Base sentence (added punctuation, to make it more interesting):
String sentence = "Say that 123 of us will come by and meet you, "
+ "say, at the woods of 123woods.";
// Split it (punctuation taken in consideration, as well):
java.util.List<String> strings =
java.util.Arrays.asList(sentence.split(" |,|\\."));
// My keywords:
java.util.ArrayList<String> keywords = new java.util.ArrayList<>();
keywords.add("123woods");
keywords.add("come");
keywords.add("you");
keywords.add("say");
// Set... ready...?
int counter = 0;
// Go!
for(String s : strings)
{
// Asking if the sentence exists in the keywords, not the other
// around, to find repeated keywords in the sentence.
Boolean found = keywords.contains(s.toLowerCase());
if(found)
{
counter ++;
System.out.println("Found: " + s);
}
}
// Statistics:
if (counter > 0)
{
System.out.println("In sentence: " + sentence + "\n"
+ "Count: " + counter);
}
// example with StringSearchAlgorithms
AhoCorasick stringSearch = new AhoCorasick(asList("123woods", "woods"));
CharProvider text = new StringCharProvider("I will come and meet you at the woods 123woods and all the woods", 0);
StringFinder finder = stringSearch.createFinder(text);
List<StringMatch> all = finder.findAll();
public class FindTextInLine {
String match = "123woods";
String text = "I will come and meet you at the 123woods";
public void findText () {
if (text.contains(match)) {
System.out.println("Keyword matched the string" );
}
}
}