簡體   English   中英

BufferedReader-在.txt文件中搜索字符串

[英]BufferedReader - Search for string inside .txt file

我正在嘗試使用BufferedReader來計算.txt文件中字符串的出現次數。 我在用:

File file = new File(path);
try {
  BufferedReader br = new BufferedReader(new FileReader(file));
  String line;
  int appearances = 0;
  while ((line = br.readLine()) != null) {
      if (line.contains("Hello")) {
         appearances++;
      }
  }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
System.out.println("Found " + appearances);

但是問題是,如果我的.txt文件包含例如字符串"Hello, world\\nHello, Hello, world!" 並且找到"Hello" ,則外觀變成兩個而不是三個,因為它只在一行中搜索字符串的一個外觀。 我該如何解決? 非常感謝

最簡單的解決方案是

while ((line = br.readLine()) != null) 
    appearances += line.split("Hello", -1).length-1;

請注意,如果您搜索的不是正則表達式保留字符 ,而是“ Hello”,則應在分割之前對字符串進行轉義:

String escaped = Pattern.quote("Hello."); // avoid '.' special meaning in regex
while ((line = br.readLine()) != null) 
    appearances += line.split(escaped, -1).length-1;

這是一種有效且正確的解決方案:

String line;
int count = 0;
while ((line = br.readLine()) != null)    
    int index = -1;
    while((index = line.indexOf("Hello",index+1)) != -1){
        count++;
    }
}
return count;

它遍歷該行,並從上一個索引+1開始尋找下一個索引。

彼得的解決方案的問題在於它是錯誤的(請參閱我的評論)。 TheLostMind解決方案的問題在於它通過替換創建了許多新的字符串,這是不必要的性能缺陷。

正則表達式驅動的版本:

String line;
Pattern p = Pattern.compile(Pattern.quote("Hello")); // quotes in case you need 'Hello.'
int count = 0;
while ((line = br.readLine()) != null)    
    for (Matcher m = p.matcher(line); m.find(); count ++) { }
}
return count;

我現在對這個版本和gexicide版本之間的性能感到好奇-當我獲得結果時會進行編輯。


編輯:在〜800k日志文件上運行100次,以查找在開始時一次,在中端左右一次,在末尾一次以及整個過程中多次發現的字符串作為基准。 結果:

IndexFinder: 1579ms, 2407200hits. // gexicide's code
RegexFinder: 2907ms, 2407200hits. // this code
SplitFinder: 5198ms, 2407200hits. // Peter Lawrey's code, after quoting regexes

結論:對於非正則表達式字符串,repeated-indexOf方法最快,而且速度很快。

基本基准代碼(來自原始Ubuntu 12.04安裝的日志文件):

public static void main(String ... args) throws Exception {
    Finder[] fs = new Finder[] {
        new SplitFinder(), new IndexFinder(), new RegexFinder()};
    File log = new File("/var/log/dpkg.log.1"); // around 800k in size
    Find test = new Find();
    for (int i=0; i<100; i++) {
        for (Finder f : fs) {
            test.test(f, log, "2014"); // start
            test.test(f, log, "gnome"); // mid
            test.test(f, log, "ubuntu1"); // end
            test.test(f, log, ".1"); // multiple; not at start
        }
    }
    test.printResults();
}        
 while (line.contains("Hello")) { // search until line has "Hello"
 appearances++;
 line = line.replaceFirst("Hello",""); // replace first occurance of "Hello" with empty String
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM