Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

325
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!