Búsqueda de texto sin usar expresiones regulares en Python

Digamos que quiere encontrar un número de teléfono americano en una cadena (string). Usted conoce el patrón si es estadounidense: tres números, un guión, tres números, un guión y cuatro números. He aquí un ejemplo: 415-555-4242.

Utilicemos una función llamada isPhoneNumber() para comprobar si una cadena coincide con este patrón, devolviendo True o False. Abre una nueva pestaña del editor de archivos e introduce el siguiente código; luego guarda el archivo como isPhoneNumber.py:

def isPhoneNumber(text):
  ➊ if len(text) != 12:
         return False
     for i in range(0, 3):
      ➋ if not text[i].isdecimal():
             return False
  ➌ if text[3] != '-':
         return False
     for i in range(4, 7):
      ➍ if not text[i].isdecimal():
             return False
  ➎ if text[7] != '-':
         return False
     for i in range(8, 12):
      ➏ if not text[i].isdecimal():
             return False
  ➐ return True

print('Is 415-555-4242 a phone number?')
print(isPhoneNumber('415-555-4242'))
print('Is Moshi moshi a phone number?')
print(isPhoneNumber('Moshi moshi'))

Cuando se ejecuta este programa, la salida tiene el siguiente aspecto:

Is 415-555-4242 a phone number?
True
Is Moshi moshi a phone number?
False

La función isPhoneNumber() tiene un código que realiza varias comprobaciones para ver si la cadena de texto es un número de teléfono válido. Si alguna de estas comprobaciones falla, la función devuelve False. Primero el código comprueba que la cadena tiene exactamente 12 caracteres ➊. A continuación, comprueba que el código de área (es decir, los tres primeros caracteres del texto) esté formado sólo por caracteres numéricos ➋. El resto de la función comprueba que la cadena sigue el patrón de un número de teléfono: el número debe tener el primer guión después del código de área ➌, tres caracteres numéricos más ➍, luego otro guión ➎, y finalmente cuatro números más ➏. Si la ejecución del programa consigue superar todas las comprobaciones, devuelve True ➐.

Si se llama a isPhoneNumber() con el argumento ‘415-555-4242’ se obtendrá True. Llamar a isPhoneNumber() con ‘Moshi moshi’ devolverá False; la primera prueba falla porque ‘Moshi moshi’ no tiene 12 caracteres.

Si quisiera encontrar un número de teléfono dentro de una cadena más grande, tendría que añadir aún más código para encontrar el patrón del número de teléfono. Sustituya las cuatro últimas llamadas a la función print() en isPhoneNumber.py por lo siguiente:

message = 'Call me at 415-555-1011 tomorrow. 415-555-9999 is my office.'
for i in range(len(message)):
  ➊ chunk = message[i:i+12]
  ➋ if isPhoneNumber(chunk):
          print('Phone number found: ' + chunk)
print('Done')

Cuando se ejecute este programa, la salida tendrá el siguiente aspecto:

Phone number found: 415-555-1011
Phone number found: 415-555-9999
Done

En cada iteración del bucle for, se asigna un nuevo trozo de 12 caracteres del mensaje a la variable chunk ➊. Por ejemplo, en la primera iteración, i es 0, y a chunk se le asigna message[0:12] (es decir, la cadena «Llámame a las 4»). En la siguiente iteración, i es 1, y al chunk se le asigna el mensaje[1:13] (la cadena ‘all me at 41’). En otras palabras, en cada iteración del bucle for, chunk toma los siguientes valores:

  • ‘Call me at 4’
  • ‘all me at 41’
  • ‘ll me at 415’
  • ‘l me at 415-‘
  • . . . and so on.

Se pasa el chunk a isPhoneNumber() para ver si coincide con el patrón de número de teléfono ➋, y si es así, se imprime el chunk.

Continúa el bucle a través del mensaje, y finalmente los 12 caracteres del chunk serán un número de teléfono. El bucle recorre toda la cadena, probando cada trozo de 12 caracteres e imprimiendo cualquier trozo que encuentre que satisfaga isPhoneNumber(). Una vez que hemos terminado de recorrer el mensaje, imprimimos ‘Done’.

Aunque la cadena del mensaje es corta en este ejemplo, podría tener millones de caracteres y el programa seguiría ejecutándose en menos de un segundo. Un programa similar que encuentre números de teléfono usando expresiones regulares también se ejecutaría en menos de un segundo, pero las expresiones regulares hacen que sea más rápido escribir estos programas.

Deja una respuesta