Regex за търсене и замяна на текст в голям файл

Търся многоредов шаблон в огромен файл и ако го намеря, трябва да заменя съдържанието. Искам да постигна това по ефективен за паметта начин. Текущата ми реализация чете текст от файл на парчета в 4096 байта. След това прилага regex search replace и записва резултата в изходния поток на буфера. Това ми дава някои подобрения на паметта, като не зареждам целия файл в паметта, но правя много IO с map/flush повиквания. Имам нужда от предложения за по-нататъшно подобряване на моя код. Освен това алгометърът се проваля, ако моделът, който ще се търси, е разделен на съседни части. Някакви идеи за това как ефективно търсене-замяна на текста, който се разделя на съседни части. Предположения: Текстът за търсене винаги е по-малък от 4096 байта.

public void searchAndReplace (String inputFilePath, String outputFilePath) {

    Pattern HEADER_PATTERN =  Pattern.compile("<a [^>]*>[^(</a>)]*</a>", Pattern.DOTALL);
    Charset UTF8 = Charset.forName("UTF-8");
    File outputFile = new File(outputfilepath);
    if (!outputFile.exists()) {
        outputFile.createNewFile();
    }

    FileInputStream inputStream = new FileInputStream(new File(inputfilepath));
    FileOutputStream outputStream = new FileOutputStream(outputFile);

    FileChannel inputChannel = inputStream.getChannel();

    final long length = inputChannel.size();
    long pos = 0;
    while (pos < length) {
        int remaining = (int)(length - pos) > 4096 ? 4096 : (int)(length - pos);
        MappedByteBuffer map = inputChannel.map(FileChannel.MapMode.READ_ONLY, pos, remaining);
        CharBuffer cbuf = UTF8.newDecoder().decode(map);
        Matcher matcher = HEADER_PATTERN.matcher(cbuf);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "Some text");
        }
        matcher.appendTail(sb);
        outputStream.write(sb.toString().getBytes());
        outputStream.flush();
        pos = pos + 4096;
    }

    inputStream.close();
    outputStream.close(); 
}

person Chinmay    schedule 27.03.2015    source източник
comment
Трябва ли да използвате java? Ако не, каква ОС използвате?   -  person Bohemian♦    schedule 28.03.2015
comment
Бих предпочел да използвам java, тъй като бих искал приложението да е независимо от операционната система. Бих искал да използвам OS grep/find, ако не съществува друга алтернатива.   -  person Chinmay    schedule 28.03.2015
comment
Доста сигурен е, че вашият регулярен израз не прави това, което си мислите, че прави: той изисква котвата да не съдържа нито един от знаците (, <, /, a, > or ). Мисля, че всъщност искаш "<a [^>]*>.*?</a>"   -  person Bohemian♦    schedule 29.03.2015
comment
Може би трябва да използвате стрийминг XML анализатор, за да се справите с това.   -  person Duncan Jones    schedule 02.04.2015
comment
+Дънкан : Да, в крайна сметка направих същото. Благодаря   -  person Chinmay    schedule 03.04.2015


Отговори (1)


Декларирайте списък със специални знаци, които е малко вероятно да бъдат във вашия низ. След това тествайте своя низ, за ​​да се уверите, че някой от специалните знаци не излиза вътре в него. Поставете специалния символ между областите, в които искате да направите своя регулярен израз. След това можете да направите търсене/замяна или търсене с /[^¬]*myRegExHere[^\¬]/g

person Steve Tomlin    schedule 05.05.2015