Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

326
Vistas
Regex usando una secuencia creciente de números Python

Digamos que tengo una cadena:

 teststring = "1.3 Hello how are you 1.4 I am fine, thanks 1.2 Hi There 1.5 Great!"

Que me gustaría como:

 testlist = ["1.3 Hello how are you", "1.4 I am fine, thanks 1.2 Hi There", "1.5 Great!"]

Básicamente, dividir solo en dígitos crecientes donde la diferencia es .1 (es decir, 1.2 a 1.3).

¿Hay alguna manera de dividir esto con expresiones regulares pero solo capturando números secuenciales crecientes? Escribí el código en python para iterar secuencialmente usando un re.compile() personalizado para cada uno y está bien pero es extremadamente difícil de manejar.

Algo como esto (donde parts1_temp es una lista dada de los números xx en la cadena):

 parts1_temp = ['1.3','1.4','1.2','1.5'] parts_num = range(int(parts1_temp.split('.')[1]), int(parts1_temp.split('.')[1])+30) parts_search = ['.'.join([parts1_temp.split('.')[0], str(parts_num_el)]) for parts_num_el in parts_num] #parts_search should be ['1.3','1.4','1.5',...,'1.32'] for k in range(len(parts_search)-1): rxtemp = re.compile(r"(?:"+str(parts_search[k])+")([\s\S]*?)(?=(?:"+str(parts_search[k+1])+"))", re.MULTILINE) parts_fin = [match.group(0) for match in rxtemp.finditer(teststring)]

Pero hombre, es feo. ¿Hay alguna manera de hacer esto más directamente en expresiones regulares? Me imagino que esta es una característica que alguien hubiera querido en algún momento con expresiones regulares, pero no puedo encontrar ninguna idea sobre cómo abordar esto (y tal vez no sea posible con expresiones regulares puras).

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Hacer esto con una expresión regular solo parece demasiado complejo. ¿Qué pasa con este procesamiento:

 import re teststring = "1.3 Hello how are you 1.4 I am fine, thanks 1.2 Hi There 1.5 Great!" res = [] expected = None for s in re.findall(r'\d+(?:\.\d+)?|\D+', teststring): if s[0].isdigit() and expected is None: expected = s fmt = '{0:.' + str(max(0, len(s) - (s+'.').find('.') - 1)) + 'f}' inc = float(re.sub(r'\d', '0', s)[0:-1] + '1') if s == expected: res.append(s) expected = fmt.format(float(s) + inc) elif expected: res[-1] = res[-1] + s print (res)

Esto también funciona si los números tienen 2 decimales o más, o ninguno.

over 4 years ago · Santiago Trujillo Denunciar

0

Este método usa finditer para encontrar todas las ubicaciones de \d+\.\d+ , luego prueba si la coincidencia fue numéricamente mayor que la anterior. Si la prueba es verdadera, agrega el índice a la matriz de indices .

La última línea usa la comprensión de lista tomada de esta respuesta para dividir la cadena en esos índices dados.

método original

Este método asegura que la coincidencia anterior sea más pequeña que la actual. Esto no funciona secuencialmente, sino que funciona en función del tamaño del número. Entonces, suponiendo que una cadena tenga los números 1.1, 1.2, 1.4 , se dividirá en cada aparición ya que cada número es mayor que el anterior.

Ver código en uso aquí

 import re indices = [] string = "1.3 Hello how are you 1.4 I am fine, thanks 1.2 Hi There 1.5 Great!" regex = re.compile(r"\d+\.\d+") lastFloat = 0 for m in regex.finditer(string): x = float(m.group()) if lastFloat < x: lastFloat = x indices.append(m.start(0)) print([string[i:j] for i,j in zip(indices, indices[1:]+[None])])

Salidas: ['1.3 Hello how are you ', '1.4 I am fine, thanks 1.2 Hi There ', '1.5 Great!']


Editar

Método secuencial

Este método es muy similar al original, sin embargo, en el caso de 1.1, 1.2, 1.4 , no se dividiría en 1.4 ya que no sigue secuencialmente dado el separador secuencial .1 .

El método a continuación solo difiere en la instrucción if , por lo que esta lógica es bastante personalizable según sus necesidades.

Ver código en uso aquí

 import re indices = [] string = "1.3 Hello how are you 1.4 I am fine, thanks 1.2 Hi There 1.5 Great!" regex = re.compile(r"\d+\.\d+") lastFloat = 0 for m in regex.finditer(string): x = float(m.group()) if (lastFloat == 0) or (x == round(lastFloat + .1, 1)): lastFloat = x indices.append(m.start(0)) print([string[i:j] for i,j in zip(indices, indices[1:]+[None])])
over 4 years ago · Santiago Trujillo Denunciar

0

También puede mutar la cadena para que se coloque un marcador junto al dígito si es parte de la secuencia creciente. Luego, puedes dividir en ese marcador:

 import re teststring = "1.3 Hello how are you 1.4 I am fine, thanks 1.2 Hi There 1.5 Great!" numbers = re.findall('[\.\d]+', teststring) final_string = re.sub('[\.\d]+', '{}', teststring).format(*[numbers[0]]+[numbers[i] if numbers[i] < numbers[i-1] else '*'+numbers[i] for i in range(1, len(numbers))]).split(' *')

Producción:

 ['1.3 Hello how are you', '1.4 I am fine, thanks 1.2 Hi There', '1.5 Great!']
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda