【问题标题】:Search for multiline String in a text file在文本文件中搜索多行字符串
【发布时间】:2019-10-24 00:03:44
【问题描述】:

我有一个文本文件,我试图从中搜索一个包含多行的字符串。我可以搜索单个字符串,但我需要搜索多行字符串。

我试图搜索运行良好的单行。

public static void main(String[] args) throws IOException 
{
  File f1=new File("D:\\Test\\test.txt"); 
  String[] words=null;  
  FileReader fr = new FileReader(f1);  
  BufferedReader br = new BufferedReader(fr); 
  String s;     
  String input="line one"; 

  // here i want to search for multilines as single string like 
  //   String input ="line one"+
  //                 "line two";

  int count=0;   
  while((s=br.readLine())!=null)   
  {
    words=s.split("\n");  
    for (String word : words) 
    {
      if (word.equals(input))   
      {
        count++;    
      }
    }
  }

  if(count!=0) 
  {
    System.out.println("The given String "+input+ " is present for "+count+ " times ");
  }
  else
  {
    System.out.println("The given word is not present in the file");
  }
  fr.close();
}

以下是文件内容。

line one  
line two  
line three  
line four

【问题讨论】:

  • 如果两条线不相邻怎么办?
  • 那么它不需要搜索。只有当行相邻时才应该搜索。
  • line one line two line three line four 这些是您从文件中读取的搜索值,还是您在不同位置有搜索值并在文件内搜索?

标签: java string file bufferedreader multiline


【解决方案1】:

为此使用StringBuilder,从文件中读取每一行并将它们附加到StringBuilderlineSeparator

StringBuilder lineInFile = new StringBuilder();

while((s=br.readLine()) != null){
  lineInFile.append(s).append(System.lineSeparator());
}

现在使用contains检查lineInFile中的searchString

StringBuilder searchString = new StringBuilder();

builder1.append("line one");
builder1.append(System.lineSeparator());
builder1.append("line two");

System.out.println(lineInFile.toString().contains(searchString));

【讨论】:

  • 我在一个文本文件中搜索,行数不固定,也可以是多行。那样的话你觉得可行吗?
  • 是的,看看我的代码,直到你没有文件中的所有行你怎么能检查存在的行不是? @Janny
  • 我明白你的意思,但在实际应用程序中,我不认为对“第一行”、“第二行”等值进行硬编码。在这种情况下有什么想法会有所帮助吗?
  • 您需要从某个地方读取它们吗?如何让输入行在文件中搜索? @Janny
  • 不确定是什么意思?从某个地方您需要获取内容以在文件中搜索对吗?如果您需要从另一个文件中读取它,请将其读入另一个 stringbuilder @Janny
【解决方案2】:

试试这个,

public static void main(String[] args) throws IOException {
    File f1 = new File("./src/test/test.txt");
    FileReader fr = new FileReader(f1);
    BufferedReader br = new BufferedReader(fr);
    String input = "line one";
    int count = 0;

    String line;
    while ((line = br.readLine()) != null) {
        if (line.contains(input)) {
            count++;
        }
    }

    if (count != 0) {
        System.out.println("The given String " + input + " is present for " + count + " times ");
    } else {
        System.out.println("The given word is not present in the file");
    }
    fr.close();
}

【讨论】:

  • 我要搜索多行字符串输入="line one"+ "line two";
  • 第一行第一行,第二行第二行。
【解决方案3】:

来自默认 C 的更复杂的解决方案(代码基于《C 编程语言》一书中的代码)

final String searchFor = "Ich reiß der Puppe den Kopf ab\n" +
        "Ja, ich reiß' ich der Puppe den Kopf ab";

int found = 0;

try {
    String fileContent = new String(Files.readAllBytes(
        new File("puppe-text").toPath()
    ));

    int i, j, k;
    for (i = 0; i < fileContent.length(); i++) {
        for (k = i, j = 0; (fileContent.charAt(k++) == searchFor.charAt(j++)) && (j < searchFor.length());) {
            // nothig
        }

        if (j == searchFor.length()) {
            ++found;
        }
    }
} catch (IOException ignore) {}

System.out.println(found);

【讨论】:

  • 我正在尝试用java做
  • @Janny 它是 java,但解决方案取自 C 书
【解决方案4】:

为什么不将文件中的所有行标准化为一个字符串变量,然后只计算文件中输入的出现次数。我已经使用Regex 来计算出现次数,但可以通过您认为合适的任何自定义方式来完成。

public static void main(String[] args) throws IOException 
{
        File f1=new File("test.txt"); 
        String[] words=null;  
        FileReader fr = new FileReader(f1);  
        BufferedReader br = new BufferedReader(fr); 
        String s;     
        String input="line one line two"; 

        // here i want to search for multilines as single string like 
        //   String input ="line one"+
        //                 "line two";

        int count=0;
        String fileStr = "";
        while((s=br.readLine())!=null)   
        {
            // Normalizing the whole file to be stored in one single variable
            fileStr += s + " ";
        }

        // Now count the occurences
        Pattern p = Pattern.compile(input);
        Matcher m = p.matcher(fileStr);
        while (m.find()) {
            count++;
        }

        System.out.println(count); 

        fr.close();
}

使用StringBuilder 类进行高效的字符串连接。

【讨论】:

  • 文件太长,将其标准化为单个变量是否是个好主意。
  • 是的,这绝对不是一个好主意。除了将其存储在 String 变量中之外,您还可以继续附加 StringBuilder,因为 String 赋值很慢。确定它是否有效的最好方法是运行它并检查。如果将所有内容加载到内存中是一个问题,那么我可以想到一些边缘情况可能会造成问题。
  • 最好的方法是使用最简单的解决方案,然后在需要时对其进行优化。
【解决方案5】:

试试 Scanner.findWithinHorizo​​n()

String pathToFile = "/home/user/lines.txt";
String s1 = "line two";
String s2 = "line three";

String pattern = String.join(System.lineSeparator(), s1, s2);

int count = 0;
try (Scanner scanner = new Scanner(new FileInputStream(pathToFile))) {
  while (scanner.hasNext()) {
    String withinHorizon = scanner.findWithinHorizon(pattern, pattern.length());
    if (withinHorizon != null) {
      count++;
    } else {
      scanner.nextLine();
    }

  }
} catch (FileNotFoundException e) {
  e.printStackTrace();
}
System.out.println(count);

【讨论】:

  • 它只是一个字符串而不是两个。单个字符串包含多行。
  • String.join(System.lineSeparator(), s1, s2) == "第二行" + "\n" + "第三行"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 2018-09-07
  • 2018-07-18
  • 2020-11-28
相关资源
最近更新 更多