【问题标题】:Find whole words without regex在没有正则表达式的情况下查找整个单词
【发布时间】:2011-12-11 20:19:20
【问题描述】:

我需要在一个句子中找到整个单词,但不使用正则表达式。所以如果我想在这句话中找到“the”这个词:“The quick brown fox jumps over the lazy dog”,我目前正在使用:

 String text = "the, quick brown fox jumps over the lazy dog";
 String keyword = "the";

 Matcher matcher = Pattern.compile("\\b"+keyword+"\\b").matcher(text);
 Boolean contains = matcher.find();

但如果我使用:

Boolean contains = text.contains(keyword);

并用空格填充关键字,它不会找到句子中的第一个“the”,因为它没有环绕空格和标点符号。

需要明确的是,我正在构建一个 Android 应用程序,但我遇到了内存泄漏,这可能是因为我在 ListView 中使用了正则表达式,所以它正在执行正则表达式匹配 X 个次,具体取决于 Listview 中的项目。

【问题讨论】:

  • 出于某种原因你需要空格吗?
  • “不使用正则表达式”。因为教练禁止你这样做?如果是这种情况,请添加“作业”标签。
  • 您也可以在字符串中添加空格以进行搜索。
  • 您不能使用正则表达式有什么特殊原因吗?
  • 如果这个问题是this one 的后续问题,请返回并在那里查看我的答案。你可以使用正则表达式来解决这个问题,这比你在这里尝试做的要容易得多。

标签: java regex


【解决方案1】:

如果您需要检查多个单词并且不使用正则表达式,您可以使用StringTokenizer 和空格作为分隔符。

然后您可以构建自定义搜索方法。否则,使用String.contains()String.indexOf() 的其他解决方案符合条件。

【讨论】:

  • 标点符号呢?从技术上讲,“快速的棕色狐狸”应该回归真实。
【解决方案2】:

您所做的是搜索"the"。然后对每个匹配项进行测试,看看周围的字符是否为空格(或标点符号),或者匹配项是否分别位于字符串的开头/结尾。

【讨论】:

    【解决方案3】:
    public int findWholeWorld(final String text, final String searchString) {
        return (" " + text + " ").indexOf(" " + searchString + " ");
    }
    

    这将为您提供单词“the”的第一次出现的索引,如果单词“the”不存在,则为 -1。

    【讨论】:

    • 我的答案在这种情况下不起作用。您仍然希望执行indexOf 之类的操作,然后检查字符串前后的字母是否是字符串的开头/结尾或不是字符(如果您允许连字符,则为连字符)。
    【解决方案4】:

    在空格上拆分字符串,然后查看结果数组是否包含您的单词。

    【讨论】:

    • 技术上String.split() 使用正则表达式:)
    【解决方案5】:

    只需遍历字符并将它们继续存储在 char 缓冲区中。每次看到空格时,将缓冲区清空到单词列表中,然后继续直到到达末尾。

    【讨论】:

      【解决方案6】:

      在 StringTokenizer.class 的 cmets 中:

      StringTokenizer 是一个遗留类,保留用于 兼容性原因,尽管在新代码中不鼓励使用它。它是 建议任何寻求此功能的人使用拆分 String 或 java.util.regex 包的方法。

      以下示例说明如何将 String.split 方法可用于将字符串分解为其基本标记:

      String[] result = "this is a test".split("\\s");
      for (int x=0; x<result.length; x++)
          System.out.println(result[x]);
      

      打印以下输出:

      this
      is
      a
      test
      

      遍历生成的字符串数组并测试相等性并保持计数。

      for (String s : result)
      {
       count++;
      }
      

      如果这是家庭作业,请告诉您的讲师阅读 Java,时代已经改变。我记得在学校里有完全相同的愚蠢问题,这对你为现实世界做准备没有任何帮助。

      【讨论】:

        【解决方案7】:

        我有一个项目需要全词匹配,但是我不能使用正则表达式(因为正则表达式转义了一些关键字),我尝试编写自己的代码用非正则表达式来模拟它(\bxxx\b) ,我只知道C#,而且效果很好。

        public static class Finder
        {
            public static bool Find(string? input, string? pattern, bool isMatchCase = false, bool isMatchWholeWord = false, bool isMatchRegex = false)
            {
                if (String.IsNullOrWhiteSpace(input) || String.IsNullOrWhiteSpace(pattern))
                {
                    return false;
                }
        
                if (!isMatchCase && !isMatchRegex)
                {
                    input = input.ToLower();
                    pattern = pattern.ToLower();
                }
        
                if (isMatchWholeWord && !isMatchRegex)
                {
                    int len = pattern.Length;
                    int suffix = 0;
        
                    while (true)
                    {
                        int start = input.IndexOf(pattern, suffix);
        
                        if (start == -1)
                        {
                            return false;
                        }
        
                        int end = start + len - 1;
        
                        int prefix = start - 1;
                        suffix = end + 1;
        
                        bool isPrefixMatched, isSuffixMatched;
        
                        if (start == 0)
                        {
                            isPrefixMatched = true;
                        }
                        else
                        {
                            isPrefixMatched = IsWord(input[prefix]) != IsWord(input[start]);
                        }
        
                        if (end == input.Length - 1)
                        {
                            isSuffixMatched = true;
                        }
                        else
                        {
                            isSuffixMatched = IsWord(input[suffix]) != IsWord(input[end]);
                        }
        
                        if (isPrefixMatched && isSuffixMatched)
                        {
                            return true;
                        }
                    }
                }
        
                if (isMatchRegex)
                {
                    if (isMatchWholeWord)
                    {
                        if (!pattern.StartsWith(@"\b"))
                        {
                            pattern = $@"\b{pattern}";
                        }
        
                        if (!pattern.EndsWith(@"\b"))
                        {
                            pattern = $@"{pattern}\b";
                        }
                    }
        
                    return Regex.IsMatch(input, pattern, isMatchCase ? RegexOptions.None : RegexOptions.IgnoreCase);
                }
        
                return input.Contains(pattern);
            }
        
            private static bool IsWord(char ch)
            {
                return Char.IsLetterOrDigit(ch) || ch == '_';
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-12-30
          • 2020-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-21
          相关资源
          最近更新 更多