PDA

Ver la Versión Completa : [ IDEA ] Alternativa a "Separar variable" para sacar datos de un archivo de texto


WillyWeb
11/06/15, 21:54:25
Muy buenas a tod@s :-)

Sigo repasando el recopilatorio en modo esponja y no paro de encontrar ideas realmente brillantes. :ok:

El listón está muy alto y no es nada fácil aportar ideas nuevas, pero he visto en más de un proyecto algo que yo hago de otra forma ... sacar información de un archivo de texto descargado (xml, html y cosas así).

En casi todos los proyectos se descarga el archivo con "HTTP Get", se pasa el contenido de la variable global %HTTPD a una local y se trocea esa variable con "Separar variable" para ir "entresacando" la parte que interesa. Indudablemente el sistema funciona, es cuestión de repetir la acción tantas veces como sea necesario para "acorralar" el trozo de información que se necesita.

No digo que siempre, pero la mayor parte de las veces eso se puede hacer más fácilmente usando una "expresión regular (http://es.wikipedia.org/wiki/Expresión_regular)" en la acción "Buscar y Reemplazar".

Lo explico con un ejemplo...

Supongamos que quieres saber la dirección de una ubicación de GPS (para saber en qué calle has dejado aparcado el coche, por ejemplo). Para eso podemos recurrir al "Google Maps Geocoding API (https://developers.google.com/maps/documentation/geocoding/)" y descargar un XML con la información requerida.

https://maps.googleapis.com/maps/api/geocode/xml?latlng=40.416947,-3.703529

<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
<status>OK</status>
<result>
<type>street_address</type>
<formatted_address>Plaza Puerta del Sol, 11, 28013 Madrid, Madrid, España</formatted_address>
<address_component>
<long_name>11</long_name>
<short_name>11</short_name>
<type>street_number</type>
</address_component>
<address_component>
<long_name>Plaza Puerta del Sol</long_name>
<short_name>Plaza Puerta del Sol</short_name>
<type>route</type>
</address_component>

... y así más de 600 líneas.

Lo que nos interesa está entre las etiquetas <formatted_address>, y yo lo extraigo así...


A1: Buscar y Reemplazar Contenido de Variable [ Variable:%HTTPD Buscar:<formatted_address>.*?</formatted_address> Una sola coincidencia:Encendido Almacenar Coincidencias En:%httpd ]
A2: Buscar y Reemplazar Contenido de Variable [ Variable:%httpd1 Buscar:<.*?> Reemplazar Coincidencias:Encendido Reemplazar Con:nada ]


La primera acción saca de la variable %HTTPD (la variable de Tasker asociada a HTTP Get) todo lo que está entre las primeras etiquetas <formatted_address> que encuentre y lo deja en %httpd1.

La segunda acción elimina de %httpd1 todo lo que tenga el aspecto de una etiqueta.

Edito para añadir la excelente sugerencia de mlesir de usar look around asertions

Cambiando la expresión regular que he puesto en A1 por esta otra ...

(?<=<formatted_address>).*?(?=</formatted_address>)

... el resultado que buscamos es inmediato y no necesitamos A2, así que la cosa quedaría así ...


A1: Buscar y Reemplazar Contenido de Variable [ Variable:%httpd Buscar:(?<=<formatted_address>).*?(?=</formatted_address>) Una sola coincidencia:Encendido Almacenar Coincidencias En:%httpd ]


Y ahora sí. El resultado está en%httpd1 limpio de polvo y paja ;-)

Hasta la próxima ... :cucu:

mlesir
11/06/15, 22:12:07
Bueno ante todo Willy gracias y enhorabuena por la aportación.

La segunda acción sobraría si usas los look around asertions.
Básicamente lo que hacen es coger la coincidencia que esta entre los look arounds pero sin incluir estos en el resultado. Tienes la información aquí:

http://developer.android.com/reference/java/util/regex/Pattern.html

Sigue aportando y compartiendo así, a mucha gente le servirá. Espero que lo te he comentado te sirva para mejorar tu idea.

WillyWeb
11/06/15, 22:17:06
Pues gracias por la información. No conocía esa posibilidad. Lo probaré en Tasker y ya contaré el resultado :ok:

WillyWeb
12/06/15, 11:08:35
Ya está probado...

Tasker "traga" perfectamente con ese tipo de expresión y, como decía mlesir, con una pequeña modificación en la primera acción se puede evitar la segunda. Cambiando la expresión regular que puse en mi ejemplo por esta otra ...

(?<=<formatted_address>).*?(?=</formatted_address>)

... el resultado que buscamos es inmediato.

Por cierto, por la forma en que Tasker se comporta ante las expresiones regulares (no requiere escapar ciertos caracteres especiales) yo diría que es compatible con el formato de regex que se usa en python.

El que quiera aprender más sobre el tema de los "lookaround" que mire en...

(la página propuesta por mlesir)
http://developer.android.com/reference/java/util/regex/Pattern.html

(dos páginas con más detalles y ejemplos)
http://www.rexegg.com/regex-lookarounds.html
http://www.regular-expressions.info/lookaround.html

(páginas que suelo utilizar para probar las regex)
https://regex101.com/
http://www.rexv.org/

Estoy cambiando unas tareas en las que usaba todo esto. En lo que las tenga listas las comparto.

Gracias colega :ok: ... me encantan estas cosas X-D