【问题标题】:Replacing text from a file in Java用Java替换文件中的文本
【发布时间】:2014-07-22 21:18:18
【问题描述】:

我一直在尝试用 java 创建一个简单的程序,将一些单词替换到文件中。要将文本更改为我创建的文件,我创建了一个字符串并将其设置为文件文本:

Path path = Paths.get("somePath/someFile.someExtension");
Charset charset = StandardCharsets.UTF_8;
String s = new String(Files.readAllBytes(path), charset);

编辑:要使用s 保存到文件,我使用了Files.write(path, s.getBytes(charset));

然后我用s.replaceAll("A", "B") 之类的命令更改字符串。但现在,我被困住了。我想做一个更复杂的,然后用“B”替换“A”。我会尽力解释:

我需要在文件中查找wall someNumber someNumer someNumber是否在其中,并且如果有三个参数(someNumber someNumber someNumber),则在中心获取“someNumber”的值。例如:

如果命令是:

wall 200 500 100
wall 200 500 100

然后我想从中心获取参数(在第一种情况下为 500,在第二种情况下为 500),并将其存储到变量中,然后将其从字符串中删除。之后,在这些命令的顶部(在示例中为wall 200 500 100 wall 200 500 100),我想写:

usemtl texture
ceil (someNumber that we stored, in the case, 500)

请注意,如果参数wall wall 没有任何分隔符(例如#other wall),则中间的 someNumber 将相等(500 和 500 相等)。因此,下面的命令将仅按组显示(例如,如果 wall wall wall... 没有与 #other wall 分隔)。

其他示例,这将是之前/之后的文件:

之前:

wall 100 300 50
wall 100 300 100
wall 100 300 400

之后:

usemtl texture
ceil 300

wall 100 50
wall 100 100
wall 100 400

那么,我该如何做这个替换呢?

请回答!我不知道怎么做!

编辑:向@Roan 提问,大部分代码的所有者:

现在,@Roan 的答案代码转换为:

package com.fileConverter.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import javax.swing.JFileChooser;

public class FileReplace extends JFileChooser {
    private static final long serialVersionUID = -254322941935132675L;

    private static FileReplace chooser = new FileReplace();

    public static void main(String[] args) {
        chooser.showDialog(chooser, "Open");
    }

    public void cancelSelection() {
        System.exit(0);
    }

    public void approveSelection() {
        super.approveSelection();
        System.out.println("starting...");

        // The path were your file is
        String path = chooser.getSelectedFile().getAbsolutePath();
        File file = new File(path);

        // try to create an inputstream from the file
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            // If we are here the file is not found
            e.printStackTrace();
        }

        // make it a buffered reader
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(fis));

        // to store the current line
        String line;

        // array to store the different words
        String[] words;

        // create a second temporally file that will replace the original file
        File file2 = new File(chooser.getSelectedFile().getParentFile()
                + "$$$$$$$$$$$$$$$.tmp");
        try {
            file.createNewFile();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        // and create the streams
        FileOutputStream file2Os = null;
        try {
            file2Os = new FileOutputStream(file2);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        PrintWriter writer = new PrintWriter(file2Os);
        try {
            System.out.println("replacing code...");
            writer.println("mtllib textures.mtl");
            // loop through all lines and
            while ((line = bufferedReader.readLine()) != null) {
                line = line
                        .replace("//", "#")
                        .replace("(", "wall")
                        .replace(")", "\n")
                        .replace("{", "")
                        .replace("}", "")
                        .replace("# brush from cube",
                                "room cube" + countWords(line, "cube"))
                        .replace(" NULL 0 0 0 1 1 0 0 0", "")
                        .replace("\"classname\"", "")
                        .replace("\"worldspawn\"", "");

                // get all the diffent terms
                words = line.split(" ");

                // see if there are 4 terms in there: wall x x x
                // and if the first term equals wall28
                // and if the middle number is the number you want to delete
                // if not just copy the line over

                if (words.length == 4 && words[0].contains("wall")) {
                    double doubleVal = Double.parseDouble(words[2]);
                    int val = (int) doubleVal;
                    // now modify the line by removing the middel number
                    String newLine = words[0] + " " + words[1] + " " + words[3];
                    String valInsert = null;

                    if (val >= 0)
                        valInsert = "\n" + "usemtl texture" + "\n" + "ceil "
                                + val;
                    else if (val < 0)
                        valInsert = "\n" + "usemtl texture" + "\n" + "floor "
                                + val;

                    // write this to the new file
                    writer.println(valInsert);
                    writer.println(newLine);
                } else {
                    // copy the old line
                    writer.println(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // close our resources
        writer.close();
        try {
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // now we rename the temp file and replace the old file
        // with the new file with the new content
        file.delete();
        file2.renameTo(file);

        System.out.println("done!");
    }

    public int countWords(String string, String word) {
        int lastIndex = 0;
        int count = 0;

        while (lastIndex != -1) {

            lastIndex = string.indexOf(word, lastIndex);

            if (lastIndex != -1) {
                count++;
                lastIndex += word.length();
            }
        }
        return count;
    }
}

问题是这部分没有做任何替换:

if (words.length == 4 && words[0].contains("wall")) {
    double doubleVal = Double.parseDouble(words[2]);
    int val = (int) doubleVal;
    // now modify the line by removing the middel number
    String newLine = words[0] + " " + words[1] + " " + words[3];
    String valInsert = null;

    if (val >= 0)
        valInsert = "\n" + "usemtl texture" + "\n" + "ceil "
                + val;
    else if (val < 0)
        valInsert = "\n" + "usemtl texture" + "\n" + "floor "
                + val;

    // write this to the new file
    writer.println(valInsert);
    writer.println(newLine);
}

我该如何解决?另一件事,这部分是假设创建一个在检查多维数据集写入次数后增长的数字,但它也不起作用:(

.replace("# brush from cube", "room cube" + countWords(line, "cube"))

countWords 方法:

public int countWords(String string, String word) {
    int lastIndex = 0;
    int count = 0;

    while (lastIndex != -1) {

        lastIndex = string.indexOf(word, lastIndex);

        if (lastIndex != -1) {
            count++;
            lastIndex += word.length();
        }
    }
    return count;
}

非常感谢

【问题讨论】:

  • 请澄清您的问题。你想写:PS....
  • 是的,我知道它看起来很复杂。我修复了PS,现在尝试再次阅读。有不明白的可以评论,我会一一解答。

标签: java string file replace


【解决方案1】:

好的,我不确定我是否理解正确。
这是我对你的问题的解释:
你有一个文件,上面写着:wall [number] [number] [number]
现在您要检查是否有 3 个数字,然后删除中间的数字,如果它是您要搜索的数字。

所以我会这样做:
在您运行程序之前,您需要在 C: 驱动器上创建一个名为“text”的文件夹,在该文件夹中,您需要一个名为 text.txt 的文件,其中包含您的格式:例如:
墙 123 300 320
如果您更改数字的值,您可以指定中间数字必须在哪个数字才能被删除。

public class FileReplace {

public static void main(String[] args){
    //The path were your file is
    String path = "C:\\text\\text.txt";
    File file = new File(path);

    //The number you want to delete
    int number = 300;

    //try to create an inputstream from the file
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        //If we are here the file is not found
        e.printStackTrace();
    }

    //make it a buffered reader
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));

    //to store the current line
    String line;

    //array to store the different words
    String[] words;

    //create a second temporally file that will replace the original file
    File file2 = new File("C:\\text\\$$$$$$$$$$.tmp");
    try {
        file.createNewFile();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    //and create the streams
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file2);
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    }
    PrintWriter writer = new PrintWriter(fos);
    try {
        //loop through all lines and 
        while((line = bufferedReader.readLine()) != null){
            //get all the diffent terms
            words = line.split(" ");

            //see if there are 4 terms in there: wall x x x
            //and if the first term equals wall
            //and if the middle number is the number you want to delete
            //if not just copy the line over
            if(words.length == 4 && words[0].equals("wall") && words[2].equals(String.valueOf(number))){
                //now modify the line by removing the middel number
                String newLine = words[0] + " " + words[1] + " " + words[3];

                //write this to the new file
                writer.println(newLine);
            }else{
                //copy the old line
                writer.println(line);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    //close our resources
    writer.close();
    try {
        bufferedReader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    //now we rename the temp file and replace the old file
    //with the new file with the new content
    file.delete();
    file2.renameTo(file);
}

}
如果您对此代码有任何疑问,请随时向他们提问。
哦,您可能还需要以管理员权限运行它,因为它使用文件。

希望这会有所帮助。

【讨论】:

  • 好的,很高兴我能帮上忙。我需要修改我的代码还是您现在可以自己处理?
  • 好的,如果我有时间我会修改它,如果你愿意。但是理解代码并能够自己修改它也可能是一个好主意。因此,如果您对此有任何疑问。随便问我。
  • 要检查它是否为负,请执行以下操作: if(Integer.parseInt(words[2])
  • 你是这个意思吗? : if(Integer.parseInt(words[2])
  • 如果它在程序中,您可以执行 text.replace("//", "#");
【解决方案2】:

要分析字符串并查看它是否匹配(“wall” number number number),您可以使用 REGEX 表达式:请参阅文档 here

要使用正则表达式,只需将 .matches() 应用于您的 String 变量,它会根据格式是否经过验证返回 true 或 false。

如果格式被验证,那么只需使用 SubString 函数,指定开始和结束索引,以便获得中间数。 要取出它,你可以做相反的事情。 SubString 开头(直到中间数字),然后 SubString 结尾(中间数字之后的所有内容),然后使用这 2 个创建一个新字符串。

【讨论】:

  • 感谢您的回答。我会试试看。 +1
  • 感谢您的回答和其他人的帮助,我解决了我的问题。
【解决方案3】:

不使用(显式)正则表达式的简单解决方案是使用令牌拆分String(在您的情况下,它是一个空格。

line = "wall 100 300 50";
String[] words = line.split("\\s+");

然后您可以将单词 [2] 转换为 int 等。然后您可以写回一个新文件(或者如果您已读取所有文件内容,则相同)。

正则表达式更强大,但对我来说有点吓人,所以你可以选择任何符合你需求的东西。

【讨论】:

  • 感谢您的回答。我也试试。 1+
  • "\\s+" 是正则表达式,它被翻译为 1 个或多个空格(与正则表达式匹配)。这可能是 1,2,3 个空格,1 个或多个制表符制表符 (\t) 等。有关详细信息,请参阅正则表达式
  • 感谢您的回答和其他人的帮助,我解决了我的问题。
【解决方案4】:

您可以使用它来计算一个单词在字符串中出现的次数:
尝试 1:

public static int countWords(String string, String word) {
    //get all individual words
    String[] terms = string.split(" ");
    //this variable counts how many times word occurs
    int count = 0;
    //a count variable for the loop
    int counter = 0;
    //loop through all the words and if we see a word that equals word we add one to the count variable
    while(counter < terms.length){
        //check if the term equals the word
        if(terms[counter].equals(word)){
            //the term matched add one to the count variable
            count++;
        }
        counter++;
    }
    //return the number of occurrences
    return count;
}



尝试 2:

public static String countWords(String string, String word) {
    //get all individual words
    String[] terms = string.split(" ");
    //this variable counts how many times word occurs
    int count = 0;
    //a count variable for the loop
    int counter = 0;

    StringBuffer sb = new StringBuffer();
    sb.append("1");
    //loop trough all the words and if we see a word that equals word we add one to the count variable
    while(counter < terms.length){
        //check if the term equals the word
        if(terms[counter].equals(word)){
            //the term matched add one to the count variable
            count++;
            sb.append(" " + word + (count + 1));
        }
        counter++;
    }
    //return the number of occurrences
    return sb.toString();
}<br><br>

尝试 3:您的代码中需要有一个名为 lastVar 的静态变量:

static int lastVar = 0;
public static String countWords(String string, String word) {
    //get all individual words
    String[] terms = string.split(" ");
    //this variable counts how many times word occurs
    int count = 0;
    //a count variable for the loop
    int counter = 0;

    StringBuffer sb = new StringBuffer();
    sb.append("1");
    //loop trough all the words and if we see a word that equals word we add one to the count variable
    while(counter < terms.length){
        //check if the term equals the word
        if(terms[counter].equals(word)){
            //the term matched add one to the count variable
            count++;
            sb.append(" " + word + (count + 1 + lastVar));
        }
        counter++;
    }
    lastVar += count + 1;
    //return the number of occurrences
    return sb.toString();
}


应该可以。

希望这会有所帮助:D。

【讨论】:

  • 我不完全明白。你有一条带立方体的线,后面有一个数字吗?
  • 啊,所以你想把这个:cube cube cube cube 改成:cube1 cube2 cube3 cube4 ?
  • 另外如果是cube0也有效?
  • 已更新。这项工作有点不同,但如果该行例如:room cube cube cube cube 之后将是 room cube1 cube2 cube3 cube4。附言它现在返回一个字符串,该字符串位于您所拥有的字符串之后。
  • 我在电脑上运行程序的另一个问题是:usemtl texture ceil 323 wall 234 234 so...
【解决方案5】:

要重新格式化立方体线,您可以使用:
尝试1:

// loop through all lines and
        while ((line = bufferedReader.readLine()) != null) {
            if(line.contains("// brush from cube")){
                line = line.replace("// brush from cube ", "").replace("(", "").replace(")", "");
                String[] arguments = line.split("\\s+");
                line = "cube" + Cube + " usemtl texture ceil " + arguments[2] + " wall " + arguments[1] + " " + arguments[3] + " usemtl texture floor " + arguments[5] + " wall " + arguments[4] + " " + arguments[6];
                Cube++;
            }
            line = line
                    .replace("//", "#")
                    .replace("(", "wall")
                    .replace(")", "\n")
                    .replace("{", "")
                    .replace("}", "")
                    .replace(" NULL 0 0 0 1 1 0 0 0", "")
                    .replace("\"classname\"", "")
                    .replace("\"worldspawn\"", "");


尝试 2:

// loop through all lines and
        while ((line = bufferedReader.readLine()) != null) {
            if(line.contains("// brush from cube")){
                line = line + bufferedReader.readLine() + " " + bufferedReader.readLine();
                line = line.replace("// brush from cube ", "").replace("(", "").replace(")", "");
                String[] arguments = line.split("\\s+");
                line = "cube" + Cube + " usemtl texture ceil " + arguments[2] + " wall " + arguments[1] + " " + arguments[3] + " usemtl texture floor " + arguments[5] + " wall " + arguments[4] + " " + arguments[6];
                Cube++;
            }
            line = line
                    .replace("//", "#")
                    .replace("(", "wall")
                    .replace(")", "\n")
                    .replace("{", "")
                    .replace("}", "")
                    .replace(" NULL 0 0 0 1 1 0 0 0", "")
                    .replace("\"classname\"", "")
                    .replace("\"worldspawn\"", "");


附言我只发布了重要的部分。您应该能够看到它在代码中的位置。此外,您还需要在代码中的某处有一个名为 cube 的静态 int:

static int Cube = 1;


如果它不起作用,应该是它,让我知道! :D

【讨论】:

  • 嗯,很奇怪,我想我会看看能不能找到问题。
  • 我遇到了一个问题,我用你的文件运行了代码,但我没有收到错误...顺便说一句,我确实假设每个画笔都在它自己的行。
  • 啊,这就是原因。我的方法需要//从立方体(400 100 200)(300 -100 300)刷子都在一条线上。顺便说一句,你如何做灰色突出显示?我将重写该方法以满足您的需求。 :)
  • 对了,输出中还有回车吗?
  • 好吧,顺便说一句,回车是换行符或 \n
猜你喜欢
  • 2017-06-06
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2021-04-04
  • 2016-06-11
相关资源
最近更新 更多