[英]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.