在字符串中搜索单词

如果我在字符串中查找特定单词,例如,在字符串“你好吗”我正在寻找“是”。 常规indexOf()工作得更快更好还是正则表达式匹配()

String testStr = "how are you"; String lookUp = "are"; //METHOD1 if (testStr.indexOf(lookUp) != -1) { System.out.println("Found!"); } //OR //METHOD 2 if (testStr.match(".*"+lookUp+".*")) { System.out.println("Found!"); } 

上面两种方法中的哪一种是在另一个字符串中查找字符串的更好方法? 还是有更好的选择?

  • Ivard

如果你不关心它是否真的是你匹配的整个单词,那么indexOf()将会快得多。

另一方面,如果你需要能够区分areharebrainedaren't等等,那么你需要一个正则表达式: \bare\b只匹配整个单词( \\bare\\b在Java)。

\b是单词边界锚,它匹配字母数字字符(字母,数字或下划线)和非字母数字字符之间的空格。

警告:这也意味着如果你的搜索词实际上不是一个单词(假设你正在寻找### ),那么这些单词边界锚只会匹配像aaa###zzz这样的字符串,但不会+++###+++

进一步警告:默认情况下,Java对于构成字母数字字符的内容有一个有限的世界观。 这里只有ASCII字母/数字(加上下划线)计数,因此单词边界锚点会在élèverelevéärgern等单词上失败。 在这里阅读更多相关信息(以及如何解决此问题) 。

方法一应该更快,因为它的开销较小。 如果它是关于在大型文件中搜索的性能,那么像boyer moore模式匹配这样的专门方法可以带来进一步的改进。

如果你正在寻找一个固定的字符串,而不是一个模式,就像你问题中的例子一样, indexOf会更好(更简单)和更快,因为它不需要使用正则表达式。

此外,如果您要搜索的字符串确实包含在正则表达式中具有特殊含义的字符,则使用indexOf您无需担心转义这些字符。

通常,尽可能使用indexOf ,并match模式匹配,其中indexOf无法indexOf您的需要。

第一种方法更快,因为它不是一个复杂的表达式,所以没有理由在这里使用正则表达式。

如果你在另一个字符串中查找一个字符串 ,你应该使用indexOfcontains方法。 示例:查看字符串中是否存在"foo"

但如果您正在寻找模式,请使用match方法。
示例:查看字符串开头/结尾是否显示"foo" 。 或者看看它是否作为一个整体词出现。

由于正则表达式引擎开销,使用match方法进行简单的字符串搜索效率不高。

当然indexOf()match()更好。 一个’匹配()’由许多比较组成:a == a,r == r,e == e; 同时,您附加了通配符,这些通配符可分为多种情况:

  1. ?是
    ??是
    ???是
    ????是
    ……..是吗? 是?? 是???

直到它与原始字符串一样长。

你的问题几乎可以回答自己; 如果你不得不正则表达式是否是更好的选择,那几乎肯定不是。 此外,当您在正则表达式和非正则表达式解决方案之间进行选择时,性能永远不应成为您的主要标准。 等到你有一些工作代码并对其进行分析。

比较两个版本的更好方法是分析indexOf方法的源代码和regex.matches方法本身,计算Big_O_notation中算法实现的运行时间并比较它们的最佳,平均和最差情况(在开始时,中间发现的分析序列)或分别结束字符串)。 源代码在这里是indexOf_source ,这里是regex.matches 。 我们需要对两者进行运行时分析,以了解它究竟在做什么。 忙碌的任务,但它是进行真正比较的唯一方法,其余的只是假设。 不错的问题。

我用它:

 public boolean searchStr(String search, String what) { if(!search.replaceAll(what,"_").equals(search)) { return true; } return false; } 

使用示例:

 String s = "abc"; String w = "bc"; if(searchStr(s,w)) { //this returns true } s="qwe"; w="asd"; if(searchStr(s,w)) { //this returns false }