首页 > 解决方案 > JAVA - 如何使用正则表达式模式替换二进制文件 (.exe) 中的字符串

问题描述

我需要读取一个名为“chromedriver.exe”的文件,并替换所有出现的以“cdc_”开头且长度为 26 个字符的字符串。所以,我的正则表达式是“cdc_.{22}”。这匹配一个以“cdc_”开头的字符串,之后有 22 个字符。(字符串示例 -> cdc_kwjeorialeksjeiwRTkwjr)

我的替换将是这个 26 个字符的字符串“plp_roepstdlwoeproslPOweos”。

我在 python(不是我的)中有这个代码,可以完成我上面描述的操作,但我需要将它转换为 Java。 所以问题是:我如何在 Java 中做到这一点?请帮忙。

import io
import re
import string

replacement = "plp_roepstdlwoeproslPOweos".encode()

with io.open("chromedriver.exe", "r+b") as fh:
    for line in iter(lambda: fh.readline(), b""):
        if b"cdc_" in line:
            fh.seek(-len(line), 1)
            newline = re.sub(b"cdc_.{22}", replacement, line)
            fh.write(newline)

标签: javapythoniowebdriverselenium-chromedriver

解决方案


这是一种快速而肮脏的方法。将文件读入字节数组,搜索文本,如果找到则替换,然后写回文件。

private void replace(String filename) throws Exception
{
    File file=new File(filename);
    int length=(int)file.length();
    byte[] data;
    try(FileInputStream in = new FileInputStream(file); 
        ByteArrayOutputStream bs=new ByteArrayOutputStream(length))
    {
        byte[] buffer=new byte[128_000];
        int len=0;
        while((len=in.read(buffer))>0)
            bs.write(buffer,0,len);
        in.close();
        bs.close();
        data=bs.toByteArray();
    }
    searchAndReplace(data);
    
    try(FileOutputStream out=new FileOutputStream(file);
        ByteArrayInputStream bs=new ByteArrayInputStream(data))
    {
        byte[] buffer=new byte[128_000];
        int len=0;
        while((len=bs.read(buffer))>0)
            out.write(buffer,0,len);
        bs.close();
        out.flush();
        out.close();
    }
}

private void searchAndReplace(byte[] data)
{
    byte[] replacements="plp_roepstdlwoeproslPOweos".getBytes(StandardCharsets.US_ASCII);
    byte[] first="cdc_".getBytes(StandardCharsets.US_ASCII);
    Pattern test=Pattern.compile("cdc_.{22}");
    
    for(int i=0;i<data.length-replacements.length;i++)
    {
        if(data[i]==first[0] && data[i+1]==first[1] && data[i+2]==first[2] && data[i+3]==first[3]) // check for consecutive bytes 
        {
            String text=new String(data, i, replacements.length, StandardCharsets.US_ASCII);
            if(test.matcher(text).matches()) // found it
            {
                System.arraycopy(replacements, 0, data, i, replacements.length);
                i+=replacements.length;
            }
        }
    }
}

推荐阅读