Pergunta

Como eu faço on-the-fly pesquisa e substituir em um córrego Java (entrada ou saída)?

Eu não quero carregar o fluxo na memória ou em um arquivo.

Eu só ver os bytes passando e eu preciso fazer algumas substituições. As sequcias a serem substituídos são curtas (até 20 bytes).

Foi útil?

Solução

Você pode usar a classe fornecido aqui se as regras de substituição estáticos são suficientes para você.

Outras dicas

Você poderia implementar um determinista finito autômato que olha para cada byte apenas uma vez (por exemplo, não lookbehind é necessário), de modo que você seria basicamente transmitir a entrada através de um máximo de retenção tampão tantos personagens como o comprimento do seu padrão, saída padrão em um jogo ou transbordamento (não pareado) caracteres quando avançando no padrão. Runtime é linear após a preparação do padrão.

Wikipedia tem algumas informações sobre padrão de correspondência e como isso funciona na teoria.

Eu tenho algumas boas idéias a partir do link fornecido e acabou escrevendo uma pequena classe de substituição alça de $ var $ variáveis ??em um córrego. Para a posteridade:

public class ReplacingOutputStream extends OutputStream {
    private static final int DOLLAR_SIGN = "$".codePointAt(0);
    private static final int BACKSLASH = "\\".codePointAt(0);
    private final OutputStream delegate;
    private final Map<String, Object> replacementValues;

    private int previous = Integer.MIN_VALUE;
    private boolean replacing = false;
    private ArrayList<Integer> replacement = new ArrayList<Integer>();


    public ReplacingOutputStream(OutputStream delegate, Map<String, Object> replacementValues) {
        this.delegate = delegate;
        this.replacementValues = replacementValues;
    }

    public @Override void write(int b) throws IOException {
        if (b == DOLLAR_SIGN && previous != BACKSLASH) {
            if (replacing) {
                doReplacement();
                replacing = false;
            } else {
                replacing = true;
            }
        } else {
            if (replacing) {
                replacement.add(b);
            } else {
                delegate.write(b);
            }
        }

        previous = b;
    }

    private void doReplacement() throws IOException {
        StringBuilder sb = new StringBuilder();
        for (Integer intval : replacement) {
            sb.append(Character.toChars(intval));
        }
        replacement.clear();

        String oldValue = sb.toString();
        Object _newValue = replacementValues.get(oldValue);
        if (_newValue == null) {
            throw new RuntimeException("Could not find replacement variable for value '"+oldValue+"'.");
        }

        String newValue = _newValue.toString();
        for (int i=0; i < newValue.length(); ++i) {
            int value = newValue.codePointAt(i);
            delegate.write(value);
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top