Tengo un proyecto de Python donde esencialmente estoy codificando un lenguaje personalizado, y para ello necesito una función que pueda reemplazar las cadenas ingresadas por el usuario con diferentes datos, por ejemplo, números aleatorios (es difícil explicar lo que quiero hacer c :)

Un ejemplo de esto sería que el usuario escribe en la línea de comando:

j@dev-box$ file write hi.txt {RANDOM_INT[1, 20]}

Y la función se ejecutaría como:

parseOutput = parseFunction(userInputString) # userInputString = "file write hi.txt {RANDOM_INT[1,20]}

Entonces parseOutput sería igual a file write hi.txt 14, con el número aleatorio en lugar de la etiqueta {RANDOM_INT [x, x]}

Espero haber aclarado lo que estoy buscando, ya que es difícil de explicar.

-1
Jay Williams 7 jun. 2016 a las 20:25

3 respuestas

La mejor respuesta

Bueno, en lugar de usar la cadena de plantilla de Python (que son potentes pero limitadas), le sugiero que use plantillas Jinja2.

Este motor de plantillas es conocido por desarrollar aplicaciones web.

Para implementar su idioma personalizado, puede usar filtros . Aquí hay un ejemplo:

Primero importe los módulos requeridos:

import random

from jinja2.environment import Environment

Defina un filtro para calcular un número aleatorio, como este:

def random_int(value, x, y):
    return "{0}".format(random.randint(x, y))

nota: el parámetro valor no se usa aquí.

Defina un entorno Jinja y agregue su filtro personalizado:

env = Environment()
env.filters["RANDOM_INT"] = random_int

Luego puede usarlo de esta manera (debe cambiar ligeramente la entrada del usuario para cumplir con la sintaxis de la plantilla Jinja):

user_input = 'file write hi.txt {{ "" | RANDOM_INT(1, 10) }}'
template = env.from_string(user_input)
result = template.render()

El resultado:

print(result)
# file write hi.txt 9

Ventajas: Jinja puede verificar la sintaxis y los formatos que faltan por usted.

EDITAR: más ejemplos

Puede cambiar la configuración del entorno para usar llaves simples en lugar de dobles:

env = Environment(variable_start_string="{", variable_end_string="}")

En lugar de crear un filtro personalizado, puede usar funciones y filtros incorporados. Por ejemplo: use la función range() con el filtro random:

user_input = 'file write hi.txt { range(10) | random }'
template = env.from_string(user_input)
result = template.render()
print(result)

Finalmente, puede ampliar el contexto global con sus propias funciones

env = Environment(variable_start_string="{", variable_end_string="}")
env.globals["RANDOM_INT"] = random.randint

user_input = 'file write hi.txt { RANDOM_INT(1, 10) }'
template = env.from_string(user_input)
result = template.render()
print(result)
0
Laurent LAPORTE 8 jun. 2016 a las 05:24

Puede intentar utilizar la funcionalidad str.find de Python. Documentación

Ejemplo:

def parseFunction(input):
     index = input.find('{') # or look for more i.e. find('{RANDOM_INT')
     return input[:index] + ' ' + randomInt # remember to add the space

Puede generar randomInt utilizando random.randInt de la biblioteca integrada random.py. Documentación

0
aznbanana9 7 jun. 2016 a las 17:40

¿Es esto lo que necesitabas?

import re
import random
def parseFunction(string):
    matches = re.match('.*\{r\[(\d+),(\d+)\]\}.*',string)
    rand = random.randint(int(matches.groups()[0]), int(matches.groups()[1]))
    result = re.sub('\{r\[(\d+),(\d+)\]\}',str(rand),string)
    return result
0
Brian 7 jun. 2016 a las 17:54