@Lekim
Se que esto te va a gustar tan poco como cuando te aconsejé que era absurdo e ineficiente utilizar los wrappers de Vb6 en Vb.Net (el código fuente habla por si solo), y se que no te gustan mis "tochos", no me cojas más manía...
pero ahí va:
Utilizando el sistema de las expresiones regulares con Regex ocurre que sólo obtiene los valores siempre y cuando estén el orden establecido en el pattern:s
En .Net, RegEx se debería utilizar solamente cómo último recurso, cuando no nos quedan ideas para llevar a cabo esa tarea, o para escribir algoritmos con más rapidez cuando nos es indiferente el rendimiento y solo queremos acabar de escribir el algoritmo, pero lo cierto es que siempre habrá otro recurso más óptimo que reemplace a RegEx si estamos desarrollando en .Net. A pesar de lo que he dicho, el motor RegEx de .Net es sofisticadísimo, ahora no recuerdo en que principios/fórmulas se basa (soy un inepto en matemáticas de todas formas), pero en ciertas circunstancias puede superar en velocidad a un simple String.Split.
Dicho esto, algo muy importante a tener en cuenta es que los motores RegEx no se idearon ni diseñaron para parsear Html o lenguajes de markups en general; es un completo
overkill hacer eso, con respecto al rendimiento y estabilidad de tu algoritmo en general.
De todas formas, si, puedes hacerlo.
Si desconoces el orden de los factores entonces no debes utilizar índices de grupos, debes construir los grupos tu mismo.
Fíjate que el indexer de la class
GroupCollection tiene un overload que acepta un nombre de grupo:
...Eso debería llevarte a la siguiente conclusión: se pueden agrupar las capturas por nombres de grupo.
Para ello, esta es la sintaxis adecuada:
(?<NombreDeGrupo>|Expresión de búsqueda)
donde
(? es la apertura de grupo.
Aquí tienes la solución, pero he eliminado el atributo
height para que hagas tu el resto del trabajo
:
Dim value1 As String = "<img width=""128"" src=""...""/>"
Dim value2 As String = "<img src=""..."" width=""256""/>"
Dim rgx As New Regex("img\s+(src\=.+width\=\""(?<width>|(\d+))\""|width\=\""(?<width>|(\d+))\"".+src\=.+)")
Console.WriteLine(rgx.Match(value1).Groups("width").Value)
Console.WriteLine(rgx.Match(value2).Groups("width").Value)
Aquí tienes otro código de ejemplo:
EDITO: Y aquí más info sobre el tema (pero cuidado, la sintaxis RegEx es para
perl):
¿Como puedo obtener los valores independientemente del orden en que se encuentren?
Como te indiqué arriba es la manera de hacerlo mediante expresiones regulares, pero como también dije al principio, no se debe hacer,
la razón es simple, aparte de que no es apto, no es lo recomendable por Microsoft, y RegEx es un mecanismo (muy) lento;
aparte de todo eso también es completamente innecesario, ya que la maravillosa IDE de Microsoft tiene un interprete/parser en tiempo de diseño para lenguajes de markups, es practicamente lo mismo para Html y Xml.
Una manera sería tan sencilla como obtener el string del documento que quieres parsear, convertirlo a otro formato más amistoso para la tarea (
HtmlDocument o
XDocument), obtener el elemento (mediante LINQ, o una expresión XPath, o el intérprete en tiempo de diseño), y leer el atributo del elemento.
Pseudo-ejemplo:
Dim html As XDocument = XDocument.Load("source-code")
Dim value As String = html.<body>.<element>.@attribute
Otro ejemplo:
Dim el As XElement =
<img src="..."
height="128"
width="128"
alt="..."
/>
Dim width As Integer = CInt(el.@width)
Dim height As Integer = CInt(el.@height)
PD: Además, siempre puedes optar por utilizar los métodos de esas classes si lo prefieres en lugar de parsear el documento en tiempo de diseño.
Saludos