import asyncio import re import time from datetime import datetime detection_timer = 0 detection_timer_increment = 5 detection_timer_change = 10 x, y , z = None, None, None x_aux, y_aux, z_aux = 0, 0, 0 def get_coords(input_coords): input_coords = input_coords.replace("@","0") #convierte todos los posibles caracteres @ en caracteres 0 m = re.match(r".*:\s*([0-9.]*?)\s*,\s*([0-9.]*?)\s*,\s*([0-9.]*?)$", input_coords) #No agarra los numeros negativos if m: return m.groups() async def timer(): global x, y, z, x_aux, y_aux, z_aux global input_coords global detection_timer, detection_timer_change detection_timer += detection_timer_increment #Debe entrar a este if cara cierto tiempo if(detection_timer >= detection_timer_change): detection_timer = 0 #resetea contador #detect_color() r = get_coords(input_coords) if r: x_aux = x = float(r[0]) if r[0] else x y_aux = y = float(r[1]) if r[1] else y z_aux = z = float(r[2]) if r[2] else z return x_aux, y_aux, z_aux while True: #Some examples of possible inputs #input_coords = "Coordenadas: @, 63, -5|hhhf♀" #input_coords = "Coordenadas: @, 63.5, -5.695|hhhf♀" #input_coords = "Coordenadas: @, hhkjkm♀-63ss, -5|hhhf♀" #input_coords = "Coordenadas: -8, 63, -5 \n♀" input_coords = "Coordenadas: @, 63, -5" x_aux, y_aux, z_aux = asyncio.run(timer()) if(x_aux != None and y_aux != None and z_aux != None): print(x_aux) print(y_aux) print(z_aux)Aunque el código no funciona bien, por si son coordenadas negativas o si hay más valores al final de la cadena. ¿Cómo debo corregir esta expresión regular para que pueda capturar los valores de ejemplo que puse en el código?
"Coordenadas: @, 63, -5|hhhf♀" ----> esto debería extraer 0,63,-5
"Coordenadas: @, 63.5, -5.695|hhhf♀" ----> esto debería extraer 0,63.5,-5.695
"Coordenadas: @, hhkjkm♀-63ss, -5|hhhf♀" ----> esto debería extraer 0, -63, -5
"Coordenadas: -8, 63, -5 \n♀" ----> esto debería extraer -8,63,-5
"Coordenadas: @, 63, -5" ----> esto debería extraer 0,63,-5
Parece que podría simplemente encontrar los números y rellenarlos con ceros a la izquierda si tiene menos de 3 valores:
s = "Coordenadas: @, hhkjkm♀-63ss, -5|hhhf♀" import re l = re.findall('-?\d+', s) out = [0]*(3-len(l))+list(map(int, l) Salida: [0, -63, -5]
NÓTESE BIEN. si espera valores decimales, utilice '-?\d+(?:\.\d*)?' y float
Si desea capturar los 3 valores en 3 grupos de captura (donde su código reemplaza el @ a 0), puede:
$ para afirmar el final de la cadena-hhkjkm♀-63ss, -5|hhhf♀El patrón podría parecerse a:
^[^:]*:\s*(-?\d+(?:\.\d+)?),\D*?(-?\d+(?:\.\d+)?)\D*?(-?\d+(?:\.\d+)?)Demostración de expresiones regulares
import re def get_coords(input_coords): input_coords = input_coords.replace("@", "0") m = re.match(r"^[^:]*:\s*(-?\d+(?:\.\d+)?),\D*?(-?\d+(?:\.\d+)?)\D*?(-?\d+(?:\.\d+)?)", input_coords) if m: return m.groups() strings = [ "Coordenadas: @, 63, -5|hhhf♀", "Coordenadas: @, 63.5, -5.695|hhhf♀", "Coordenadas: @, hhkjkm♀-63ss, -5|hhhf♀", "Coordenadas: -8, 63, -5 \n♀", "Coordenadas: @, 63, -5" ] for s in strings: print(get_coords(s))Producción
('0', '63', '-5') ('0', '63.5', '-5.695') ('0', '-63', '-5') ('-8', '63', '-5') ('0', '63', '-5')Con sus muestras mostradas, inspirándose en la respuesta de Thefourthbird; por favor intente seguir regex también.
^".*?:\s*(-?\d+(?:\.\d+)?),\D*?(-?\d+(?:\.\d+)?).*?(-?\d+(?:\.\d+)?)Demostración en línea para la expresión regular anterior
Explicación: agregando una explicación detallada de lo anterior.
^".*?:\s* ##Matching from starting of value " followed by lazy match to match till 1st occurrence of : followed by 0 or more occurrences of spaces. (-?\d+(?:\.\d+)?) ##Creating 1st capturing group which has optional - as a match followed by 1 or more digits followed by optional .digits(to catch floating numbers). ,\D*? ##Matching non-digits 0 or more occurrences of it. (-?\d+(?:\.\d+)?) ##Creating 2nd capturing group which has - as optional match followed by by 1 or more digits followed by optional .digits(to catch floating numbers). .*? ##Mentioning lazy match here. (-?\d+(?:\.\d+)?) ##Creating 3rd capturing group which matches optional - here, 1 or more digits followed by optional .digits(to catch floating numbers).