如何使用Java检查一个单词是否出现在句子中?

33

我刚开始学习编程,并尝试编写一个函数,以便在句子中返回true如果存在某个单词。我使用了indexOf()方法,但是我也遇到了一个问题:

假设我的句子是I am a, Java Programmer.

如果我们使用indexOf()方法查找单词ram,它将返回true,因为ram出现在Programmer中,而正确的输出应该是false,因为ram不是作为单词而是作为一个字符串出现。

我该如何解决这个问题? 我目前正在使用的代码是:

boolean isPresent(String word, String sentence)
{
    if(sentence.indexOf(word) >= 0)
        return true;
    else
        return false;
}

注意:单词ram仅是我当前方法中存在问题的例子之一。并不是我一直要处理ram。这个单词可以是任何一个,比如上面句子中跟随逗号的a等。

更新:感谢大家提供评论和解决方案。我已经选择了一个接受的答案(如果允许的话,我会选择更多 :-)),但很多回答都很有用。


2
你可以使用 string.split 方法,然后检查生成的数组是否包含你要查找的单词。 - takendarkk
3
顺便说一下,你可以把那个函数的定义简化成这样:return sentence.indexOf(word) >= 0; - sentence.indexOf(word) >= 0 要么是 true,要么是 false,因此根据情况,这要么表示 return true;,要么表示 return false; - Panzercrisis
这个问题很明确完整,但我可以在Stackoverflow和许多其他地方找到这个问题的答案。 - Abu Sulaiman
@AbuSulaiman,在这种情况下,您应该投票将此问题标记为重复,而不仅仅是留下评论。 - Raedwald
请参见http://stackoverflow.com/questions/15779632/find-exact-word-in-a-sentence-using-java。 - Raedwald
显示剩余2条评论
12个回答

40

尝试使用正则表达式

boolean contains = s.matches(".*\\bram\\b.*");

\b 表示单词边界


4
使用单词边界符号加一分(可以舍弃 .*)。 - Salman A
2
如果我没记错的话,在Java中,整个s必须与给定的正则表达式完全匹配,因此.*必须保留。 - Teepeemm
使用空格分词器来解决这个问题难道不是更加技术上正确的做法吗? - Darth Egregious
@Fuser97381 如果没有额外的前/后处理(由于逗号),使用空格分词器在搜索“a”时会失败。 - Izkata
4
在Java中,你必须保留".*"在两端。 - Bohemian
显示剩余2条评论

21

由于您想要搜索一个单词,有三种情况:

  1. 句子开头的单词表示没有空格但结尾有空格。
  2. 句子中间的单词两端都有空格。
  3. 句子结尾的单词只有结尾有空格。

为了涵盖这三种情况,一种可能的解决方案是:

String str = "I am a JAVA programmer";
String[] splited = str.split("\\b+"); //split on word boundries
Arrays.asList(splited).contains("ram"); //search array for word

这里是可运行的演示


如果操作者想要进行不区分大小写的单词搜索,该怎么办? - Gundamaiah
如果OP需要的话,我可以建议他查看https://dev59.com/RmUp5IYBdhLWcg3wdXWa#15269846。 - Zaheer Ahmed
那如果OP的例子中有逗号(如果他们在搜索a的话)呢? - Izkata
分割单词边界是否也会返回单词间序列? - Bergi

10

问题:

如何定义一个单词?

可能的回答:

一堆由其他字符分隔开的字符。这第二组字符是由你选择的内容定义的。假设你选择它们为. ,?;。因此,如果你使用这些字符(称为界定符)分割输入字符串,你将得到一堆字符串,它们是单词。现在,为了找出输入是否包含该单词,循环遍历这些字符串以检查它们是否与你的查询匹配。

代码:

boolean isPresent(String query, String s) {    
    String [] deli = s.split("[.\\s,?;]+");

    for(int i=0;i<deli.length;i++)
        if(query.equals(deli[i]))
            return true;

    return false;    
}

简述:

如果您想将一个单词定义为由字母、数字和下划线组成的任何内容,那么有一个正则表达式可供使用:\ W +

String [] deli = s.split("\\W+");

如果你想了解更多关于Java正则表达式的知识,请考虑阅读这篇文章


3
不错的回答,不过需要注意split可以接受正则表达式。因此,你可以根据空格、非字母字符或其他方式进行分割。此外,你可以使用equalsIgnoreCase来匹配大写字母开头的单词。 - Tim B
正如@TimB所提到的,String.split采用正则表达式字符串。这意味着两件事情。首先,您无法像那样提供一个字符列表(它将尝试使用整个字符串作为正则表达式模式匹配单个边界),但是您可以使用正则表达式字符类("[.,?;]")。其次,任何正则表达式元字符都必须被转义 - 您使用的"."将匹配任何单个字符,"?"将使","可选。 - Bob
虽然这个答案很好,因为它帮助读者思考需要发生什么,但重要的是要注意\\b是一个可用的元字符,用于指示单词边界,这正是OP正在寻找的东西。但一定要区分\\b(单词边界)和\b(退格),哦! - Brian S
你不应该在字符类中使用或(|)。这不是字符类的工作方式。 - Bob
2
按单词边界拆分,不会返回单词之间的序列吗?我本来期望使用s.split("\\W+")(虽然这可能会产生空字符串,但我不确定Java中的方法如何工作)。 - Bergi
@Bergi 你说得完全正确。我在Java方面的专业知识不够,不知道\W+的存在。谢谢! - HelloWorld123456789

2

如果你想在包含标点符号的句子中匹配一个单词,你需要使用以下这个正则表达式:

  static boolean matchesWord(String toMatch, String matchIn) {
     return Pattern.matches(".*([^A-Za-z]|^)"+toMatch+"([^A-Za-z]|$).*", matchIn);
  }

(您可以使用\W,但这不会将下划线视为标点符号。)
仅在开头和结尾连接空格无法匹配字符串“I am a Java programmer”中的单词“programmer”,因为末尾没有空格。它也无法匹配标点符号之前或之后的单词。

2

1
这不适用于整个句子。String.matches() 只有在整个字符串匹配时才返回 true - user3490218
所以你可以这样做 "*\\s+" + word + "\\s+*" 作为你的正则表达式,对吧?那应该适用于句子...(可能不是正确的语法,但这是大致的想法)。 - awksp
1
是的。那样做(有点)可行。我还建议在Java文档中查找“Pattern”和“Matcher”对象。两者都是用于正则表达式字符串匹配的类,前者用于模式生成,后者用于搜索。(显然) - user3490218

1
String s="I am a JAVA programmer";
    String s1="JAVA";
    String []p=s.split("\\s*(=>|,|\\s)\\s*");
        for(int i=0;i<p.length;i++)
        {
            if(s1.equals(p[i]))
            {
                System.out.println(p[i]);
            }

        }

1
假设每个单词之间都有空格,这段代码就可以正常工作。为了更加清晰,我添加了主函数。如果单词不存在,find_str返回-1;否则,它会返回单词相对于其他单词的位置。在这里,2将被返回,表示第二个单词是“am”。
import java.util.*;
public class HelloWorld{

    public static void main(String []args){
        String str="I am a Java Programmer";
        String str1="am";
        int x=find_str(str,str1);
        System.out.println(x);

    }

    public static int find_str(String main,String search) {

        int i; 
        int found=-1;

        String[] s=main.split(" ");
        for(i=0;i<s.length;i++)
        {
            if(search.equals(s[i]))
            found=i+1;
        }
        return found;
    }
}

如果在“str1”后面有标点符号,这个方法就不起作用了。 - Teepeemm
你可能是对的。我甚至没有想到过那个。让我看看能否找到一个解决方法。 - Tina T

1
更简单的方法是:如果你认为一个单词是像这样的东西 "My pc there is ram memory"(在空格之间),你可以在indexOf函数中连接单词前后的空格,就像这样:if (sentence.indexOf(" "+ word +" ") >= 0) {

2
嗨@jhonis.souza,欢迎来到StackOverflow。您可能需要考虑要查找的单词是句子中的第一个或最后一个的情况-例如,如果有人试图在句子“Hello world”中查找单词* Hello*,并且没有前导空格,您将如何处理? - cf-
是的,你说得对!我尝试在这里使用的方法不够确切,正确的方法是使用split或regex,我只是想展示一种更简单的解决方法或另一种思考问题的方式,哈哈。感谢你的纠正。 - jhonis.souza
1
改为 (" " + sentence + " ").indexOf.. - Salman A

0

尝试这个解决方案

    int index = sent.indexOf(find);
    if (index != -1) {
        if (index == 0) {
            System.out.println("true");
        }
        else if (index + find.length() == sent.length())
        {
            System.out.println("true");
        }
        else if (sent.charAt(index - 1) == ' ' && sent.charAt(find.length() + index) == ' ') {
            System.out.println("true");
        } else {
            System.out.println("false");
        }

    } else {
        System.out.println("false");
    }

如果您想要比原始问题更多的内容,那么您应该检查空格是否不在0-9和a-Z之间,这应该涵盖任何逗号、句号等字符。

2
如果句子开头有单词,那么它就不会在开头有空格,同样地,对于结尾也是如此。 - Zaheer Ahmed
如果“will”是句子的第一个单词,这将无法正常工作。 - Gundamaiah
你好。假设我的单词是“我”,那么你的答案会是什么? - Karthikeyan Sukkoor
如果我想在上面的句子“我是一个Java程序员”中搜索“a”,根据您的代码,它将返回False,因为在索引+1之后你会看到一个逗号,对吧? - user2966197
如果你想更新你的问题并包含这一点,那么我会简单地添加代码来检查索引+1是否不在0-9和a-Z之间。 - Scary Wombat
实际上我还没有更新问题。逗号在 a 后面一开始就存在。 - user2966197

0
你好。你可以将句子拆分为数组,然后放入列表中。之后,你可以使用contains方法来检查你的单词是否存在。请尝试以下代码。
import java.util.ArrayList;
import java.util.Arrays;


 public class karthitest {
  public static void main(String[] args) {
    String sentence = "I am Karthick";
    String word = "I";

    if(isWordExist(sentence, word)){
    System.out.println("Word is exist");
    }
}

public static boolean isWordExist(String sentence, String word){
    boolean ans = Boolean.FALSE;        
    ArrayList<String> wordList = null;

    try {

        if(sentence != null && word != null){
            wordList = new ArrayList<String>(Arrays.asList(sentence.split("[^a-zA-z]+")));              
            if(wordList.contains(word)){
                ans = Boolean.TRUE;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        // TODO: handle exception
    }
    return ans;
}

}

如何在“我是Karthick,你不是”中搜索“Karthick”? - Scary Wombat
根据您的代码,您将获得以下标记:I am Karthick, you are not - Scary Wombat
我已经测试了句子中的所有三个单词,并得到了正确的答案。 - Karthikeyan Sukkoor
尝试使用以下编程代码:String sentence = "我是Kathrick,你好吗?";String word = "Kathrick,"; - Scary Wombat
以上的代码是正确的,对吧?如果是这样的话,为什么要给我投反对票呢? - Karthikeyan Sukkoor
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接