2013-01-16 4 views
0

나는 현재 생성 된대로 mysqldump의 출력을 수정하는 프로그램에서 작업하고 있는데, 현재 나는 크기가 고정 된 바이트 수를 덩어리로 mysqldump의 출력에서 ​​읽는 코드를 가지고있다. 정규 표현식 일치뿐만 아니라 정규 표현식이이 텍스트를 읽을 때마다 바꿀 수 있어야합니다 (최종 텍스트 크기가 많은 기가 바이트이기 때문에 최종 텍스트 출력에서 ​​정규식을 실행할 수 없음). 저는 PHP로 코드를 작성하고 있습니다. 문제는 (그리고 해결책이기도합니다) 언어에 의존하지 않아야한다고 생각합니다. 지금버퍼링 된 문자열에서 텍스트 바꾸기

이 같은 모습을 가지고 무엇을 psuedocode :

$previous_chunk = ""; 
while (!end_of_file($reader)) { 
    $chunk = $reader.read() //read in a few thousand characters from the file 
    $double_chunk = $previous_chunk + $chunk; 
    // do regular expressions on the double chunk (to catch matches that span the chunk boundary) 
    $output_file.write($chunk); 
    $previous_chunk = $chunk; 
} 

두 가지 문제에 좌초 실행됩니다. 첫 번째는 각 청크가 정규 표현식에 의해 두 번 평가된다는 것입니다. 따라서 청크에서 일치가 발생하면 (청크 경계를 넘지 않음) 일치하는 텍스트가 한 번만 발생하더라도 일치를 두 번 트리거합니다. 두 번째 문제는 이것이 여전히 나에게 성냥에 대한 대체를 허용하지 않는다는 것입니다. 정규 표현식은 $double_chunk에있는 텍스트를 대체하지만 출력 파일에는 $chunk이라는 글자 만 기록됩니다. 대체 파일은 영향을받지 않습니다.

하나의 생각은 내 정규식이 여러 줄 (\n 자로 구분됨)을 필요로한다는 것을 예상하지 못했기 때문에 정규식을 실행했을 때만 두 번째 버퍼를 만들 수있었습니다 줄을 입력 한 다음 청크별로 청크 대신 줄 단위로 대상 파일에 기록합니다. 불행히도, mysqldump의 출력 특성으로 인해 매우 긴 라인 (일부는 문자 그대로 수백 메가 바이트)이 있기 때문에 이것이 실현 가능한 옵션이라고 생각하지 않습니다.

합리적인 크기의 메모리 (예 : 몇 십 메가 바이트)로이 파일을 읽고 정규식으로 스트림을 수정할 수 있습니까?

답변

0
$chunk = $reader.read() //read in exactly $chunk_length characters from the file (or less iff EOF reached) 
while (!end_of_file($reader)) { 
    $previous_chunk = $chunk; 
    $chunk = $reader.read() //read in $chunk_length characters from the file (or less iff EOF reached) 

    $double_chunk = $previous_chunk + $chunk; 
    // do regular expressions on the double chunk (to catch matches that span the chunk boundary) 
    $previous_chunk = substr($double_chunk, 0, $chunk_length); 
    $chunk = substr($double_chunk, $chunk_length); 
    $output_file.write($previous_chunk); 
} 

// do regular expressions on $chunk to process the last one (or the first and only one) 
$output_file.write($chunk); 

문제 1 &이 모두가 당신이 대체 문자열로 사용하고있는 것은하지 않을 것이라는 가정, 정규식 대체하고, 다음 다시 $ previous_chunk와 $ 덩어리에 결과 문자열 청크를 할당하여 해결 다시 트리거 시합. 그러면 write이 $ previous_chunk를 사용하도록 변경되므로 다음 번에 chunk-spanning 일치를 catch 할 때 $ chunk를 변경할 수 있습니다. 또한

, 중요한, 상기 문자열이 대체되는 것으로 교체 동일한 길이임을 가정한다. 그렇지 않다면 청크 크기는 교체 후에 동적으로 변경되며 위의 솔루션은 처리하기에 너무 순진합니다. 대체 문자열이 다른 길이 인 경우 변경 청크 경계를 어떻게 든 추적해야합니다.

+0

대체품은 일치하는 문자열과 크기가 같지 않습니다 (본질적으로 "foo"를 "foobar"로 바꿉니다). 그래서 이것은 나를 위해 그것을 할 수 없습니다. 나는 두려워합니다. 나쁜 시도는 아니지만. –