Java:大文件中的正则表达式替换
JavaJava:大文件中的正则表达式替换,java,regex,Java,Regex,JavaJava.util.regex.Matcher/API返回字符串,这(如果使用默认堆大小)很可能会导致输入的OOME高达20-50M个字符。这两种方法可以很容易地重写到Writers,而不是构造stings,有效地消除了一个故障点 然而,Matcher只接受CharSequences,如果我使用Strings/StringBuffers/StringBuilders,它也可能抛出OOME 如何包装java.io.Reader以实现CharSequence接口(鉴于我的regexp可能包含
Java.util.regex.Matcher
/API返回字符串,这(如果使用默认堆大小)很可能会导致输入的OOME高达20-50M个字符。这两种方法可以很容易地重写到Writer
s,而不是构造stings,有效地消除了一个故障点
然而,Matcher
只接受CharSequence
s,如果我使用String
s/StringBuffer
s/StringBuilder
s,它也可能抛出OOME
如何包装java.io.Reader
以实现CharSequence
接口(鉴于我的regexp可能包含反向引用)?
有没有其他的解决方案可以替代文件中的regexp,并且不容易在大输入上使用OOME
换句话说,我如何在Java中实现与GNU
sed
类似的功能(众所周知,sed处理几TB大小的文件,同时支持扩展正则表达式)?因为您需要的实际上是sed
行为,所以您可以通过执行以下操作来执行它:
String[] cmdArray = {"bash", "-c", "sed 's/YourRegex/YourReplaceStr/' inputfile > output"};
Process runCmd = Runtime.getRuntime().exec(cmdArray);
我举了一个bash示例,但是如果您想在windows上运行它,您可以通过Cygwin安装sed
命令,并执行相同的命令,或者只安装用于windows的sed命令,您可以从这里下载:
对于windows,您可以使用:
String[] cmdArray = {"call", "sed 's/YourRegex/YourReplaceStr/' inputfile > output"};
Process runCmd = Runtime.getRuntime().exec(cmdArray);
我没有windows,因此无法测试上述命令,您可能需要删除call
或将call
更改为justsed
。您可以尝试的另一种选择是:
String[] cmdArray = {"cmd", "/c", "sed 's/YourRegex/YourReplaceStr/' inputfile > output"};
Process runCmd = Runtime.getRuntime().exec(cmdArray);
在这里,您可以找到一个从java执行的
dir
示例,您可以调整它以使用sed。您只需要一次替换一行,还是支持“一次替换整个文件”?Pattern.matcher()
不创建新字符串。创建的Matcher
对象只保留对传入的字符序列的引用。sed
逐行处理文件,这就是它不需要大量内存来存储大文件的原因(除非文件有很长的行或代码指示它记住很多东西)。如果您在Java中也这样做(即,读一行,处理它,打印它,读下一行,冲洗,重复),您将需要类似的内存量。顺便说一句,你可能对这个感兴趣。也许这会对你有所帮助。这是这个anwser的作者创建的。@emartinelli谢谢,这正是我想要的——一个自定义CharSequence
实现。只是不知道怎么做。谢谢,这是一个很好的解决方案,但我需要我的代码能够在没有任何Cygwin的Windows机器上运行。@Bass您也可以在Windows中使用sed
。我已经用安装它的链接更新了答案