2011-02-03 20 views
5

Así que mi problema es el siguiente, tengo un archivo que tiene el siguiente aspecto:cadenas de análisis sintáctico en pitón

[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1 

Por supuesto, esto traduce a

' This is an example file!' 

Busco una manera de analizar el contenido original en el contenido final, de modo que un [BACKSPACE] borrará el último carácter (espacios incluidos) y múltiples espacios invertidos eliminarán varios caracteres. El [SHIFT] realmente no me importa tanto. ¡Gracias por toda la ayuda!

+0

Son [RETROCESO] y [SHIFT] las únicas marcas que usted necesita preocuparse? – inspectorG4dget

Respuesta

1

Aquí hay una manera, pero se siente hackish. Probablemente haya una mejor manera.

def process_backspaces(input, token='[BACKSPACE]'): 
    """Delete character before an occurence of "token" in a string.""" 
    output = '' 
    for item in (input+' ').split(token): 
     output += item 
     output = output[:-1] 
    return output 

def process_shifts(input, token='[SHIFT]'): 
    """Replace characters after an occurence of "token" with their uppecase 
    equivalent. (Doesn't turn "1" into "!" or "2" into "@", however!).""" 
    output = '' 
    for item in (' '+input).split(token): 
     output += item[0].upper() + item[1:] 
    return output 

test_string = '[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1' 
print process_backspaces(process_shifts(test_string)) 
+0

¡Gracias! ¡Esto luce bien! –

0

Parece que usted podría utilizar una expresión regular para buscar (algo) [RETROCESO] y sustituirlo por nada ...

re.sub('.?\[BACKSPACE\]', '', YourString.replace('[SHIFT]', '')) 

No está seguro de lo que entiende por "múltiples espacios eliminar varios caracteres" .

+1

-1 ¿Cómo funcionará esto para "blah [RETROCESO] [RETROCESO] [RETROCESO] arf"? – payne

+0

Debería devolver 'barf' –

+0

Pero necesita eliminar un espacio ANTES del retroceso así como '[RETROCESO]' itslef –

1

Si no se preocupan por los cambios, simplemente despojarlos, carga

(defun apply-bspace() 
    (interactive) 
    (let ((result (search-forward "[BACKSPACE]"))) 
    (backward-delete-char 12) 
    (when result (apply-bspace)))) 

y golpeó M-x apply-bspace mientras ve su archivo. Es Elisp, no python, pero se ajusta a su requisito inicial de "something I can download for free to a PC".

Editar: Shift es más complicado si desea aplicarlo a los números demasiado (para que [SHIFT]2 =>@, [SHIFT]3 =>#, etc). La forma ingenua que funciona en letras es

(defun apply-shift() 
    (interactive) 
    (let ((result (search-forward "[SHIFT]"))) 
    (backward-delete-char 7) 
    (upcase-region (point) (+ 1 (point))) 
    (when result (apply-shift)))) 
+0

+1 para una respuesta Elisp! Es (no demasiado sorprendentemente, creo) bastante bueno en este tipo de cosas ... Soy una persona vim, personalmente, pero cosas como esta a veces me llevan hacia emacs. –

+0

@Joe Kington - Hehe.Para ser sincero, este es el tipo de cosas que manejaría con una macro de teclado y tal vez una lista a menos que hubiera varios archivos grandes que necesitaban ser analizados. Es solo que una función es más fácil de compartir y explicar. – Inaimathi

0

Es necesario leer la entrada, extraer las fichas, reconocerlos, y dar un significado a los mismos.

Esta es la forma en que lo haría:

# -*- coding: utf-8 -*- 

import re 

upper_value = { 
    1: '!', 2:'"', 
} 

tokenizer = re.compile(r'(\[.*?\]|.)') 
origin = "[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1" 
result = "" 

shift = False 

for token in tokenizer.findall(origin): 
    if not token.startswith("["): 
     if(shift): 
      shift = False 
      try: 
       token = upper_value[int(token)] 
      except ValueError: 
       token = token.upper() 

     result = result + token 
    else: 
     if(token == "[SHIFT]"): 
      shift = True 
     elif(token == "[BACKSPACE]"): 
      result = result[0:-1] 

No es el más rápido, ni la solución elegante, pero yo creo que es un buen comienzo.

espero que ayude :-)

1

Esto hace exactamente lo que quiere:

def shift(s): 
    LOWER = '`1234567890-=[];\'\,./' 
    UPPER = '[email protected]#$%^&*()_+{}:"|<>?' 

    if s.isalpha(): 
     return s.upper() 
    else: 
     return UPPER[LOWER.index(s)] 

def parse(input): 
    input = input.split("[BACKSPACE]") 
    answer = '' 
    i = 0 
    while i<len(input): 
     s = input[i] 
     if not s: 
      pass 
     elif i+1<len(input) and not input[i+1]: 
      s = s[:-1] 
     else: 
      answer += s 
      i += 1 
      continue 
     answer += s[:-1] 
     i += 1 

    return ''.join(shift(i[0])+i[1:] for i in answer.split("[SHIFT]") if i) 

>>> print parse("[SHIFT]this isrd[BACKSPACE][BACKSPACE] an example file[SHIFT]1") 
>>> This is an example file! 
+0

Vaya, acabo de descubrir un error ... lo siento. Corregirlo ahora – inspectorG4dget

+0

La depuración está completa y el resultado es exactamente lo que desea – inspectorG4dget

Cuestiones relacionadas