Ayuda con StringRegExp

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Ayuda con StringRegExp

Mensaje por avechuche »

Hola gente que tal, vengo con un problema con StringRegExp. Resulta que de una cadena de texto tengo que buscar las coincidencias.

Código: Seleccionar todo

$Cadena = 'KB2633873, KB000000'
$aArray = StringRegExp($Cadena, "KB[[:digit:]]+", 1)
Bueno eso es lo que hice yo, pero hay un problemita, el array que me devuelve tiene solo una coincidencia, la primera "KB2633873", pero me esta faltando la otra. Como puedo arreglarlo? Gracias!

PD: No estoy canchero con esto de expresiones regulares y lo que hice lo hice mas copiandome y tratando de entender. Lo que yo interpreto de lo que hice es que busque en la cadena dada una expresion que comienze con "KB" y seguido que tenga digitos, quedando "KB[[:digit:]]", pero si dejo asi tan cual me devuelve "KB2", entonces le agregue el signo "+", para que repita el caracter anterior.

EDITO

Lo solucione de una forma algo facil ¬¬ cambie el "1" por el "3" en ($Cadena, "KB[[:digit:]]+", 3). Lo que no entiendo es la finalidad de esto, la diferencia entre el "1" y el "3", debe ser para achicar el procedimiento, si se busca una coincidencia y se usa el "1" es más rapido que si tiene que listar todas la coincidencias.
jamaro
Hacker del Foro
Mensajes: 253
Registrado: 03 Nov 2010, 23:04

Re: Ayuda con StringRegExp

Mensaje por jamaro »

avechuche, efectivamente, el valor 3 devuelve la matriz de todos los valores encontrados. ¿la utilidad del valor 1? quizás lo que tu comentas.
A veces nos volvemos locos y la solución está en un valor que nos cambia todo :-)

Por cierto, no vendría mal que cuando estén solucionados los problemas o las preguntas, editáramos el título del mensaje añadiendo (Solucionado) y así el que busca algo en concreto puede saber si en un mensaje puede encontrar su solución. (Es sólo una idea ;-))
Avatar de Usuario
arkcrew
Profesional del Autoit
Mensajes: 506
Registrado: 28 Sep 2009, 19:17
Ubicación: Granada, España
Contactar:

Re: Ayuda con StringRegExp

Mensaje por arkcrew »

Hola,
Por cierto, no vendría mal que cuando estén solucionados los problemas o las preguntas, editáramos el título del mensaje añadiendo (Solucionado) y así el que busca algo en concreto puede saber si en un mensaje puede encontrar su solución. (Es sólo una idea )
Si jamaro, ciertamente sería muy útil para la gente a la hora de entrar a un tema y ver que esta o no solucionado, por eso editad el título del post y poned [SOLUCIONADO] o lo que vean conveniente que indique al usuario que la duda ha sido solventada.

Un saludo!
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

Bueno vengo con otra duda :) (Menos mal que no puse resuleto). El tema es asi.

$Cadena = "#KB123456, >KB456789, KB000000 (x86)"

Lo que necesito es que con la funcion "StringRegExp" me quede un array asi

$Array[0] = KB123456
$Array[1] = KB456789
$Array[2] = KB000000 (x86)

El problema es que no me sale, no ha caso. Gracias!
Avatar de Usuario
arkcrew
Profesional del Autoit
Mensajes: 506
Registrado: 28 Sep 2009, 19:17
Ubicación: Granada, España
Contactar:

Re: Ayuda con StringRegExp

Mensaje por arkcrew »

Hola,

Veamos, no he usado la función StringRegExp pero si te he programado un código funcional, quizás un poco chapucero, y si, probablemente se pueda optimizar más, seguroq ue le sacan trescientasmil pegas al código, pero funcional es, quita los caracteres # y > y los espacios en blanco y con la función StringSplit te saca los valores que van entre comas.

Te lo dejo aquí y le echas una ojeada:

Código: Seleccionar todo

$Cadena = "#KB123456, >KB456789, KB000000 (x86)"
$split = StringSplit($Cadena, ",")
For $a = 1 To $split[0]
	If StringInStr($split[$a], "#") Then
		$msg = StringReplace($split[$a], "#", "")
	ElseIf StringInStr($split[$a], ">") Then
		$msg = StringReplace($split[$a], ">", "")
	Else
		$msg = $split[$a]
	EndIf
	MsgBox(0, "", $msg)
Next

Esperoq eu te sirvaa!

Un saludo!
jamaro
Hacker del Foro
Mensajes: 253
Registrado: 03 Nov 2010, 23:04

Re: Ayuda con StringRegExp

Mensaje por jamaro »

avechuche, siempre que salen preguntas sobre StringRegExp recomiendo utilizar algún programa para hacer pruebas, ya que es mucho más práctico que poner el código en Autoit, ejecutarlo, comprobar el resultado y modificarlo. Hay varios en los foros de Autoit (RegExp Quick Tester, SRETester, StringRegExpGUI,...). Yo los uso mucho para hacer pruebas, hasta conseguir el resultado deseado.

Ya sabrás que Ximorro es un experto en expresiones regulares y seguro que te da alguna solución más (incluso más "estandard"), pero aquí va la mía:

Código: Seleccionar todo

KB\d+[ [(].+[)]|KB\d+
\d+ = Digitos repetidos 0 o más veces
[(] y [)] = los paréntesis (antes está el espacio)
| = Significa "o" (o lo de antes o lo de después). En comentarios que ha hecho Ximorro en este foro, indicaba, y así se hace en esta expresión, que autoit interpreta de izquierda a derecha, y si encuentra lo que está antes del "|" ya desecha lo posterior, así que ponemos primero la expresión más restrictiva, que sería que encontrara KB..... (...) y si no la encuentra, entonces KB.....
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

Gracias voy a probar con lo de jamaro, lo de StringSplit no me sirve, porque? porque yo ahi pase un codigo "limpio", yo tengo que buscar las coincidencias en un "innerhtml" que tiene 72387345872354 cosas que no me sirven.
Avatar de Usuario
arkcrew
Profesional del Autoit
Mensajes: 506
Registrado: 28 Sep 2009, 19:17
Ubicación: Granada, España
Contactar:

Re: Ayuda con StringRegExp

Mensaje por arkcrew »

Vaya, pues lástima que no funcione, simplemente basé el código en lo que me diste, si lo sé hubiera buscado otra cosa...

Saludos!
jamaro
Hacker del Foro
Mensajes: 253
Registrado: 03 Nov 2010, 23:04

Re: Ayuda con StringRegExp

Mensaje por jamaro »

aveluche, en esos casos es mejor que aportes el contenido completo del resultado de tu búsqueda, porque es probable que la solución que se dé, tampoco sea útil en otros casos.

Al igual que arkcrew yo me basé en los datos que dabas, pero si lo buscado está dentro de otras cadenas de texto, es probable que tampoco funcione la expresión regular.

Saludos.
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

No lo vi necesario porque funciona, osea no hay drama con eso. Con el ejemplo de jamaro andubo perfecto, pero me di cuenta q me falto explicar algo y que le erre en la explicacion. Resulta

Código: Seleccionar todo

$Cadena = "#KB456789, >KB456789, >KB000000 (x86)"
Lo que yo quiero ahora es que ela funcion me devuelva esto

Código: Seleccionar todo

$Array[0] = "KB456789"
$Array[1] = "KB000000 (x86)"
Yo uso este code (por ahora), pero me deja el signo ">"

Código: Seleccionar todo

$aArray = StringRegExp($Cadena, "[^#]KB\d+[ [(].+[)]|[^#]KB\d+", 3)
Dentro del innertext se repite 2 veces la misma actualizacion, una que tiene por delante el numeral "#" y la otra tiene un ">" (Que corresponde a un TAG - No siempre el mismo -). Yo quiero listar solo las actualizaciones que tienen el ">" delante, PERO que el signo ">" no aparesca.

Para jamaro: Necesito si podes explicarme esta parte del code que no entiendo.

Código: Seleccionar todo

KB\d+ = Esto lo entendi, es lo mismo que el mio, el que puse primero
[ [(].+[)] = Esta parte es confusa, porque no entiendo la finalidad del primer "[" que nunca se cierra (?). Depués del corchete esta el espacio en blanco para respetar lo que estoy buscando, pero no se que funcion cumple ese corchete. Lo que sigue lo entiendo perfectamente.
|KB\d+ = Esto tmb lo entendi
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Ayuda con StringRegExp

Mensaje por Ximorro »

avechuche, puedes simplificar [[:digit:]] con \d, así la expresión del principio queda KB\d+
La tuya está bien, que quede claro, lo digo por simplificar.

La utilidad principal del modo 1 de StringRegExp es simplemente cuando queremos comprobar que una cadena corresponde a un patrón dado. Por ejemplo cuando en una entrada de usuario queremos saber si nos ponen correctamente el formato de un email, de una fecha, etc.

jamaro, creo que pones demasiados corchetes, que son para seleccionar un carácter entre varios, pero para poner uno... simplemente lo pones.
En este caso es verdad que es especial al tratarse de paréntesis, pero con el escape es suficiente:
KB\d+ \(.+\)|KB\d+

Muy buen punto lo de poner la más restrictiva antes. ;-)
En este caso si no se me escapa nada creo que se podría hacer simplemente la parte entre paréntesis opcional, con un "?" (cero o una apariciones).
En principio:
KB\d+( \(.+\))?
Lo que pasa es que creamos un grupo que no queremos capturar, así que hay que hacerlo no capturable:
KB\d+(?: \(.+\))?
En realidad es casi tan larga como la del OR, pero creo que será más eficiente al no tener que partir el análisis en dos ramas.

avechuche, para hacer expresiones regulares hay que tener clarísimo cómo es el tipo de cadena que quieres capturar, si no es un lío. A ver si lo he entendido:
Buscas cadenas que empiezan por ">" y que están formadas por "KB" seguido de varios dígitos, y opcionalmente seguidos de un espacio y algo entre paréntesis.
Lo quieres capturar todo menos el ">".
¿Es eso?
Si el KB... empieza por algo que no sea ">" no lo quieres (da igual que sea "#" u otra cosa ¿no?).

Entonces creo que basta con añadir el ">" al principio de la expresión, pero como ya no queremos capturar toda la subcadena ponemos entre paréntesis lo demás, para indicar que queremos capturar eso:
>(KB\d+(?: \(.+\))?)
Es decir:
una cadena "KB" seguida de uno o más dígitos "\d+" y opcionalmente de un espacio seguido de algo entre paréntesis "( \(.+\))?", pero eso no lo queremos capturar aparte así que lo hacemos no capturable "(?: \(.+\))?". Todo eso "KB\d+(?: \(.+\))?" queremos que esté precedido de ">", ">KB\d+(?: \(.+\))?", pero no queremos capturar el ">" así que capturamos lo demás poniéndolo entre paréntesis:
>(KB\d+(?: \(.+\))?)

Espero que funcione como quieres...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
jamaro
Hacker del Foro
Mensajes: 253
Registrado: 03 Nov 2010, 23:04

Re: Ayuda con StringRegExp

Mensaje por jamaro »

Como siempre, el gurú de las expresiones regulares y sus clases magistrales.

La verdad es que no sé por qué puse tanto corchete, cuando, como dices los paréntesis se pueden poner \( y así lo he hecho en otras ocasiones. Pero se ve que como llevo un tiempo sin utilizarlo, se me olvidan las cosas :-)

Por cierto, ¡parece que con las expresiones regulares se puede conseguir casi todo!
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

Ximorro escribió:avechuche, puedes simplificar [[:digit:]] con \d, así la expresión del principio queda KB\d+
La tuya está bien, que quede claro, lo digo por simplificar.

La utilidad principal del modo 1 de StringRegExp es simplemente cuando queremos comprobar que una cadena corresponde a un patrón dado. Por ejemplo cuando en una entrada de usuario queremos saber si nos ponen correctamente el formato de un email, de una fecha, etc.

jamaro, creo que pones demasiados corchetes, que son para seleccionar un carácter entre varios, pero para poner uno... simplemente lo pones.
En este caso es verdad que es especial al tratarse de paréntesis, pero con el escape es suficiente:
KB\d+ \(.+\)|KB\d+

Muy buen punto lo de poner la más restrictiva antes. ;-)
En este caso si no se me escapa nada creo que se podría hacer simplemente la parte entre paréntesis opcional, con un "?" (cero o una apariciones).
En principio:
KB\d+( \(.+\))?
Lo que pasa es que creamos un grupo que no queremos capturar, así que hay que hacerlo no capturable:
KB\d+(?: \(.+\))?
En realidad es casi tan larga como la del OR, pero creo que será más eficiente al no tener que partir el análisis en dos ramas.

avechuche, para hacer expresiones regulares hay que tener clarísimo cómo es el tipo de cadena que quieres capturar, si no es un lío. A ver si lo he entendido:
Buscas cadenas que empiezan por ">" y que están formadas por "KB" seguido de varios dígitos, y opcionalmente seguidos de un espacio y algo entre paréntesis.
Lo quieres capturar todo menos el ">".
¿Es eso?
Si el KB... empieza por algo que no sea ">" no lo quieres (da igual que sea "#" u otra cosa ¿no?).

Entonces creo que basta con añadir el ">" al principio de la expresión, pero como ya no queremos capturar toda la subcadena ponemos entre paréntesis lo demás, para indicar que queremos capturar eso:
>(KB\d+(?: \(.+\))?)
Es decir:
una cadena "KB" seguida de uno o más dígitos "\d+" y opcionalmente de un espacio seguido de algo entre paréntesis "( \(.+\))?", pero eso no lo queremos capturar aparte así que lo hacemos no capturable "(?: \(.+\))?". Todo eso "KB\d+(?: \(.+\))?" queremos que esté precedido de ">", ">KB\d+(?: \(.+\))?", pero no queremos capturar el ">" así que capturamos lo demás poniéndolo entre paréntesis:
>(KB\d+(?: \(.+\))?)

Espero que funcione como quieres...
Antes que nada muchas gracias por tu tiempo.
Ahora lo acabo de probar y anda, pero no anda :). De esta forma anda perfectamente.

Código: Seleccionar todo

#Include <Array.au3>

$Cadena = ">KB548725, >KB123456 (x86), #KB000000, sssKB111111"
$aArray = StringRegExp($Cadena, ">(KB\d+(?: \(.+\))?)|KB\d+", 3)

_ArrayDisplay($aArray)
Lista cada actualizacion en una celda del array.

De esta forma no anda

Código: Seleccionar todo

#Include <Array.au3>

$Cadena = ">KB548725, >KB123456 (x86), #KB000000, sssKB111111, KB123456 (x64)"
$aArray = StringRegExp($Cadena, ">(KB\d+(?: \(.+\))?)|KB\d+", 3)

_ArrayDisplay($aArray)
Que es lo que hace? Bueno en $aArray[0] pone "KB548725", eso esta perfecto, pero en $aArray[1] pone "KB123456 (x86), #KB000000, sssKB111111, KB123456 (x64)"
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Ayuda con StringRegExp

Mensaje por Ximorro »

jamaro, gracias por el cumplido pero de gurú nada, anda que no me doy tortazos con las ER :smt005

avechuche, ahora veo que efectivamente le falta una cosita, pero de todas maneras esa no es la ER que te he pasado, ¿para qué añades ahora lo del OR? así te los pillará todos, empiecen con ">" o no...
Así que a menos que quieras hacer otra cosa, si usamos la mía:
>(KB\d+(?: \(.+\))?)

Lo que está pasando es que cuando llega a ">KB123456 (x86)" toma desde el primer paréntesis abierto y luego todo lo que puede hasta un paréntesis cerrado, que es el último de "KB123456 (x64)".
Por defecto los comodines son "avariciosos", para evitar eso hay que decir que tome el mínimo posible hasta otro paréntesis, eso se hace poniendo un "?" al comodín:
>(KB\d+(?: \(.+?\))?)

También tengo que decir que eso no es lo más eficiente, parece que la culpa es mía porque puse un ejemplo para extraer datos de un xml (algo del tipo "<item=".*?">") y luego lo he visto aplicado en muchos sitios de este foro...

Esa es la idea genérica, y generalmente es más que suficiente, pero os comento otra más eficiente. La cosa es ayudarle y, volviendo a la consulta, en vez de tomar "todo hasta el paréntesis", tomamos "todo lo que no sea paréntesis". La ER queda más larga pero sorprendentemente ERs más largas a veces son más eficientes, y en este caso se puede evitar backtrakings innecesarios si hay cadenas parcialmente correctas o si hay otros comodines involucrados.
Bueno, lo de "no paréntesis" es fácil con los corchetes, quedaría así:
>(KB\d+(?: \([^)]+\))?)
nota: dentro de corchetes el paréntesis no es especial y no hay que escaparlo.

Tampoco hay que volverse paranoico con esta optimización, ya digo que el caso anterior con el comodín "no avaricioso" suele ser suficiente. Yo una vez sí tuve problemas tratando xml muy grandes y usar una optimización como esa ayudó, así que os lo cuento por si es útil alguna vez que lo tengáis en cuenta.

(Por cierto, avechuche, si haces "quote" del comentario anterior mejor corta cosas y deja lo relevante, que repetir todo un comentario tan largo no ayuda mucho a seguir el tuyo...)
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

Gracias Ximorro por todas las explicaciones, antes que nada, las dos correcciones que hiciste son casi las correctas, PERO, siempre hay un pero.

A la solucion que me diste, tuve que modificarla un poquitin, porque solo me devolvia los que poseian los parentesis, los otros no.

Código: Seleccionar todo

#Include <Array.au3>

$Cadena = "KB123456, >KB123456 (x64), old KB123457 , >sssssKB123456 (x86), >sssssKB123456-v12"
$Reemplazo = ">(KB\d+(?: \(.+?\))?)"
$aSplit_Removed = StringRegExp($Cadena, $Reemplazo, 3) ; Actualización

_ArrayDisplay($aSplit_Removed)
Eso me devuelve [0]|KB123456 (x64), me esta robando 4 actualizaciones.

Lo primero que hice fue agregar el "|KB\d+", para que tmb me tomara los que no tienen los parentesis, pero aca surgio otro error, me listaba todas las actualizaciones, pero de todas las que tienen "parentesis", me dejaba solo la primera que encontraba, a las otras se los borraba.

Código: Seleccionar todo

#Include <Array.au3>

$Cadena = "KB123456, >KB123456 (x64), old KB123457 , >sssssKB123456 (x86), >sssssKB123456-v12"
$Reemplazo = ">(KB\d+(?: \(.+?\))?)|KB\d+"
$aSplit_Removed = StringRegExp($Cadena, $Reemplazo, 3) ; Actualización
[0]|KB123456
[1]|KB123456 (x64)
[2]|KB123457
[3]|KB123456 ; A esta le faltan los parentesis
[4]|KB123456


Lo otro que hice fue incorporar un signo "?", después del ">" y ahi se arreglaron los problemas. Quedando asi ">?(KB\d+(?: \(.+?\))?)|KB\d+".
Después de eso, sin querer borre "|KB\d+" quedando ">?(KB\d+(?: \(.+?\))?)", y anda a la perfección. NO ENTIENDO POR QUE FUNCIONA, PERO FUNCIONA, NO LE ENCUENTRO LA LOGICA POR MAS QUE LO MIRE Y LO MIRE :s


Lo que ahora encontre otro errorcito :( ... resulta que para las actualizaciones de forma "KB000000-v2", no me anda, intente algo, pero no llego :S
Llegue a esto

Código: Seleccionar todo

#Include <Array.au3>

$Cadena = "KB000000, >KB111111 (x64), old KB222222, >sssssKB333333 (x86), >sssssKB444444-v12"
$Reemplazo = ">?(KB\d+((?: \(.+?\))|(?:-v\d+))?)"
$aSplit_Removed = StringRegExp($Cadena, $Reemplazo, 3) ; Actualización

_ArrayDisplay($aSplit_Removed)
Me devuelve esto

[0]|KB000000
[1]|KB111111 (x64)
[2]| (x64)
[3]|KB222222
[4]|KB333333 (x86)
[5]| (x86)
[6]|KB444444-v12
[7]|-v12
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Ayuda con StringRegExp

Mensaje por Ximorro »

Vamos a ver, esa expresión hace lo que dije que creía que querías, por eso puse la descripción de la cadena explicándolo con palabras, para que me corrigieras si no era eso.

Me refiero a aquel trozo que empezaba 'Buscas cadenas que empiezan por ">" y que están formadas por "KB" seguido de varios dígitos...'
Como te puse se supone que tenían que empezar por ">", y así hice la ER.
En esas que pones al principio sólo te coge la del paréntesis porque es la única que empieza así. No es por el paréntesis, es por cómo empieza. Si se lo pasas a:
$Cadena = ">KB123456, >KB123456 (x64), >KB123457 , >KB123456 (x86), >KB123456-v12"
verás que te los devuelve todos. La ER sí funciona para las cadenas que describí, pero me tenías que haber dicho que no era eso lo que querías.

Por cierto, si en vez de añadir "|KB\d+" quitas el ">" de mi expresión tienes una equivalente, pero bastante más simple. En mi expresión la parte del paréntesis es opcional (por el último interrogante)
Hacer el ">" opcional con el interrogante que has añadido es en este caso equivalente a quitarlo del todo, pues no capturas ese carácter, así que si no obligas a que esté da igual que haya eso u otra cosa.

Además ahora resulta que ya no es KB más dígitos, sino que puede haber otros formatos...

Como he dicho antes para que las ER funcionen hay que tener clarísimo qué formato quieres analizar, quizás tú lo sabes pero o no lo has explicado bien o no lo he entendido, así que por favor explica con detalle cómo son las cadenas que hay que capturar con la ER.
Prefiero no hacer experimentos hasta que no me lo aclares, porque es una faena romperse la cabeza y que luego se resuelva una cosa que no se quiere y que no sirve :smt009
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Ayuda con StringRegExp

Mensaje por Chefito »

No me volvais loco a Ximorro que este foro no puede prescindir de él :smt003 . Tratármelo bien, a él y a su mente :smt002 .
La verdad es que Ximorro tiene razón. He leído el post y avechuche, no te aclaras. Cada vez vas diciendo que no va por esto otro. Así uno no se aclara. Ten claro lo que quieres, y una vez que lo tengas, expón un gran ejemplo que ocupe todas las posibilidades, explica lo que quieres recuperar, lo que quieres ignorar, etc.

Bueno, ya sabemos que Ximorro es el amo de las ER (por lo menos a mí no me cabe la menor duda). A mi me cuesta mucho este tema. Yo siempre intento ir a lo simple (yo soy simple), que si complico la expresión me lío y no se ni por donde tirar.
Ante todo agradezco a Ximorro todos sus post respecto a expresiones regulares. He aprendido mucho con ellos. Y os digo más, algunos son cursos de como utilizarlas. Yo tengo un post suyo pendiente de leer. Pero es tan largo, que lo voy retrasando :smt016 . Pero lo leeré y opinaré (seguro que es buenísimo :smt002 ).

Después de esto, yo os voy a poner algo muy sencillo por si os vale (pienso que a veces nos complicamos mucho la vida :smt005 ):

Código: Seleccionar todo

#Include <Array.au3>

$Cadena = "KB000000, >KB111111 (x64), old KB222222, >sssssKB333333 (x86), >sssssKB444444-v12"
$Cadena=$Cadena&","	;añado al final una coma a la cadena para que la expresión regular me devuelva el último elemento.
$Reemplazo = "(KB.*?),"
$aSplit_Removed = StringRegExp($Cadena, $Reemplazo, 3) ; Actualización

_ArrayDisplay($aSplit_Removed)
Pienso que avechuche vendrá diciendo que esto tampoco vale por tal texto nuevo y tal excepción, pero ahí queda lo mío :smt042 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

Vamos de nuevo :)

Lo que necesito es extrarer de una cadena los siguientes patrones >KB000000<, >KB000000 (x86)<, >KB000000-v1<, >KB000000-v1 (x86)< y >nuevo KB000000<, Todas esas actualizaciones. Las actualizaciones siempre empiezan con un ">" y terminan con "<", pero algunas tienen una palabra entre el ">" y KB.
La cadena es un innerhtml.

Llegue a esto

$Cadena = >KB000000<>KB000000 (x86)<>KB000000-v1<>KB000000-v1 (x86)<>nuevo KB000000<
$aSplit_Added = StringRegExp($Cadena , ">(KB\d+(?: \(.+?\)|-v\d+)?)<", 3)

Anda perfecto con todos, menos con el ultimo que no me lo lista.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Ayuda con StringRegExp

Mensaje por Ximorro »

Chefito por favor que me sacas los colores. Y que no, de verdad, si soy un aficionado, que me veo ER de otros y flipo en colores (buscad la ER que comprueba una dirección de mail y llorad ;-) )
Bueno lo pongo pero no hagamos un offtopic, sólo es curiosidad, aquí tenéis varias versiones, unas miran más cosas que otras:
http://regexlib.com/DisplayPatterns.asp ... eSupport=1

Y esta es la completa, la que mira la estructura que permite la norma RFC 2822:

Código: Seleccionar todo

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Volviendo a lo nuestro... Chefito, creo que lo de estar separado por comas es porque nos muestra una lista de posibilidades, pero no está así en el original.
Entonces lo que buscas está entre ">" y "<" ¡eso es muy importante porque delimita la búsqueda!
Buen trabajo con la ER, es bueno pegarse con ello.
Pero lo del v-1 tampoco va perfecto, mira por ejemplo que en el penúltimo no te toma lo del paréntesis. Es por ponerlo con un OR, es mejor ponerlo opcional, justo como lo del paréntesis.
Asumo que eso de la versión es: pegado al número del KB un signo "-" seguido de uno o más dígitos (¡y si no es esto dímelo porfa!), entonces esa parte yo la haría así:
>(KB\d+(?:-v\d+)?(?: \(.+?\))?)<

Ahora, queremos que antes del KB pueda haber "una palabra", ¿qué forma tiene esa palabra? ¿formato inglés? (eso es más fácil porque usa el ASCII básico? ¿español con acentos y demás? ¿puede haber otros signos o números?. A ver, podemos poner lo siguiente para ignorar cualquier cosa que haya antes del KB, si no puede haber varios KBxxx dentro del mismo >...< no creo que haya problemas:
>.*?(KB\d+(?:-v\d+)?(?: \(.+?\))?)<

Esto para tu última cadena devuelve:
[0] = KB000000
[1] = KB000000 (x86)
[2] = KB000000-v1
[3] = KB000000-v1 (x86)
[4] = KB000000


Como ves también está el último y los que tienen versión los toma tanto con paréntesis como sin ellos.

Pruébalo bien con datos reales porque a veces aparecen formatos que no esperábamos pero en principio para este último ejemplo funciona bien, ¡creo!
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
avechuche
Hacker del Foro
Mensajes: 188
Registrado: 13 Ago 2009, 09:53

Re: Ayuda con StringRegExp

Mensaje por avechuche »

Esto es exactamente lo que estaba buscando :) Más que gracias a tos y a ximorro por todas las explicaciones. Lo que quiero es perguntar un par de cosas con respecto a la solucion final >.*?(KB\d+(?:-v\d+)?(?: \(.+?\))?)<

Vamos por parte

>.*? = Esto significa que esta parte >.* puede aparecer o no? Entiendo que el "." es cualquier caracter (incluyendo el espacio?), el "*" es para que repita el carater anterior, pero el "?" no se sobre que parte de esto >.* trabaja. Calculo que sera sobre ".*" ya que ">" es un caracter "mio" y no un "comodin".

(?:-v\d+) = Esta parte la entiendo perfectamente "-v\d+", pero esto "?:" mas o menos, significa que lo que esta despues que eso no lo tiene que capturar en una celda aparte del array?

Ultima cosa. To lo que esta entre parentesis es lo que pone en cada celda del array?
Responder