2013-07-27 6 views
0

2147483647보다 큰 모든 정수를 대체하고 숫자의 처음 3 자리 숫자가 ^^<int>이 뒤에옵니다.파이썬에서 특정 패턴을 대체하는 방법

<stack_overflow> <isA> "QuestionAndAnsweringWebsite" "fact". 
"Ask a Question" <at> "255"^^<int> <stack_overflow> . 
<basic> "language" "89028899" <html>. 

내가 구현 한 방법은 선으로 데이터 라인을 스캔하는 것입니다 : 나는 아래에 언급 된 데이터에 의해 원래의 데이터를 대체 할

<stack_overflow> <isA> "QuestionAndAnsweringWebsite" "fact". 
"Ask a Question" <at> "25500000000"^^<int> <stack_overflow> . 
<basic> "language" "89028899" <html>. 

: 예를 들어, 나는 내 원래의 데이터가 . 2147483647보다 큰 숫자를 찾으면 처음 3 자리 숫자로 바꿉니다. 그러나 문자열의 다음 부분이 ^^<int>인지 어떻게 확인해야하는지 모르겠습니다.

내가 원하는 것은 2147483647보다 큰 숫자의 경우입니다. 예 : 25500000000, 숫자의 처음 3 자리 숫자로 바꾸고 싶습니다. 데이터의 크기가 1 테라 바이트이기 때문에 더 빠른 솔루션을 제공 할 수 있습니다. 텍스트 파일의 각 줄은 귀하의 예제처럼 보이는 경우

답변

3

적어도에서 시작해야합니다,

regex = r""" 
(    # Capture in group #1 
    "[\w\s]+" # Three sequences of quoted letters and white space characters 
    \s+   # followed by one or more white space characters 
    "[\w\s]+" 
    \s+ 
    "[\w\s]+" 
    \s+ 
) 
"(\d{10,})"  # Match a quoted set of at least 10 integers into group #2 
(^^\s+\.\s+)  # Match by two circumflex characters, whitespace and a period 
       # into group #3 
(.*)    # Followed by anything at all into group #4 
""" 

COMPILED_REGEX = re.compile(regex, re.VERBOSE) 

다음 우리를

def replace_callback(matches): 
    full_line = matches.group(0) 
    number_text = matches.group(2) 
    number_of_interest = int(number_text, base=10) 
    if number_of_interest > 2147483647: 
     return full_line.replace(number_of_interest, number_text[:3]) 
    else: 
     return full_line 

그리고 찾기 및 바꾸기 :

,312,688 ( re.RegexObject.sub 콜백 걸리므로) 교체를 처리하는 콜백 함수를 정의 할 필요가

테라 바이트의 데이터가있는 경우 메모리에서이 작업을 수행하고 싶지는 않을 것입니다. 파일을 연 다음 반복하여 데이터를 한 줄씩 바꾸고 다른 파일에 다시 쓰고 싶을 것입니다 (의심 할 여지없이이 속도를 높일 수있는 방법이 있지만 기술의 요지를 더 어렵게 만들 것입니다 :

# Given the above 
def process_data(): 
    with open("path/to/your/file") as data_file, 
     open("path/to/output/file", "w") as output_file: 
     for line in data_file: 
      fixed_data = COMPILED_REGEX.sub(replace_callback, line) 
      output_file.write(fixed_data) 
1

, 당신은이 작업을 수행 할 수 있습니다

In [2078]: line = '"QuestionAndAnsweringWebsite" "fact". "Ask a Question" "25500000000"^^ . "language" "89028899"' 

In [2079]: re.findall('\d+"\^\^', line) 
Out[2079]: ['25500000000"^^'] 

with open('path/to/input') as infile, open('path/to/output', 'w') as outfile: 
    for line in infile: 
     for found in re.findall('\d+"\^\^', line): 
      if int(found[:-3]) > 2147483647: 
       line = line.replace(found, found[:3]) 
     outfile.write(line) 

을하기 때문에 내부에 대한 루프의, 이것은 비효율적 인 해결책이 될 수있는 잠재력을 가지고있다. 그러나, 나는 순간에 더 나은 정규식 생각할 수 없다, 그래서 이것은 당신은 정규 표현식을 구성하는 re 모듈을 사용

관련 문제