Home > Blockchain >  How to extract with a regex the 3 numerical values of coordinates of this string, whether they are p
How to extract with a regex the 3 numerical values of coordinates of this string, whether they are p

Time:12-22

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)

Although the code does not work well, in case they are negative coordinates or if there are more values at the end of the string. How should I correct this regex so that it can capture the example values that I put in the code?

"Coordenadas: @, 63, -5|hhhf♀" ----> this should extract 0,63,-5

"Coordenadas: @, 63.5, -5.695|hhhf♀" ----> this should extract 0,63.5,-5.695

"Coordenadas: @, hhkjkm♀-63ss, -5|hhhf♀" ----> this should extract 0, -63, -5

"Coordenadas: -8, 63, -5 \n♀" ----> this should extract -8,63,-5

"Coordenadas: @, 63, -5" ----> this should extract 0,63,-5

CodePudding user response:

Looks like you could simply this greatly by just finding the numbers and padding with zeros on the left if you have less than 3 values:

s = "Coordenadas: @, hhkjkm♀-63ss, -5|hhhf♀"

import re
l = re.findall('-?\d ', s)
out = [0]*(3-len(l)) list(map(int, l)

Output: [0, -63, -5]

NB. if you expect decimal values, use '-?\d (?:\.\d*)?' and float

CodePudding user response:

If you want to capture all 3 values in 3 capture groups (where your code replaces the @ to 0) you can:

  • omit the anchor $ to assert the end of the string
  • match an optional -
  • note that not in all examples there is a number right after the comma like in hhkjkm♀-63ss, -5|hhhf♀

The pattern might look like:

^[^:]*:\s*(-?\d (?:\.\d )?),\D*?(-?\d (?:\.\d )?)\D*?(-?\d (?:\.\d )?)

Regex demo

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))

Output

('0', '63', '-5')
('0', '63.5', '-5.695')
('0', '-63', '-5')
('-8', '63', '-5')
('0', '63', '-5')

CodePudding user response:

With your shown samples, taking inspiration from Thefourthbird's answer; please try following regex too.

^".*?:\s*(-?\d (?:\.\d )?),\D*?(-?\d (?:\.\d )?).*?(-?\d (?:\.\d )?)

Online demo for above regex

Explanation: Adding detailed explanation for above.

^".*?:\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).
  • Related