Estoy tratando de hacer coincidir <input>
los campos tipo "ocultos" con este patrón:
/<input type="hidden" name="([^"]*?)" value="([^"]*?)" />/
Estos son datos de formulario de muestra:
<input type="hidden" name="SaveRequired" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input type="hidden" name="__VIEWSTATE3" value="ZVVV91yjY" /><input type="hidden" name="__VIEWSTATE0" value="3" /><input type="hidden" name="__VIEWSTATE" value="" /><input type="hidden" name="__VIEWSTATE" value="" />
Pero no estoy seguro de que el type
, name
y value
atributos serán siempre aparecen en el mismo orden. Si el type
atributo es el último, la coincidencia fallará porque en mi patrón está al comienzo.
Pregunta:
¿Cómo puedo cambiar mi patrón para que coincida independientemente de las posiciones de los atributos en la <input>
etiqueta?
PD: Por cierto, estoy usando la herramienta de escritorio RegEx basada en Adobe Air para probar expresiones regulares.
Respuestas:
Contrariamente a todas las respuestas aquí, porque lo que estás tratando de hacer regex es una solución perfectamente válida. Esto se debe a que NO está tratando de hacer coincidir las etiquetas equilibradas, ¡eso sería imposible con regex! Pero solo está haciendo coincidir lo que hay en una etiqueta, y eso es perfectamente regular.
Aquí está el problema, sin embargo. No puede hacerlo con una sola expresión regular ... necesita hacer una coincidencia para capturar una
<input>
etiqueta, luego hacer un procesamiento adicional sobre eso. Tenga en cuenta que esto solo funcionará si ninguno de los valores de atributo tiene un>
carácter, por lo que no es perfecto, pero debería ser suficiente para entradas sensatas.Aquí hay un código Perl (pseudo) para mostrarle lo que quiero decir:
El principio básico aquí es, no intentes hacer demasiado con una expresión regular. Como notó, las expresiones regulares imponen una cierta cantidad de orden. Entonces, lo que debe hacer en su lugar es hacer coincidir primero el CONTEXTO de lo que está tratando de extraer, luego hacer una subcordancia con los datos que desea.
EDITAR: Sin embargo, estaré de acuerdo en que, en general, usar un analizador HTML es probablemente más fácil y mejor y realmente debería considerar rediseñar su código o volver a examinar sus objetivos. :-) Pero tuve que publicar esta respuesta como respuesta a la reacción instintiva de que es imposible analizar cualquier subconjunto de HTML: HTML y XML son irregulares cuando se considera la especificación completa, pero la especificación de una etiqueta es bastante regular , ciertamente dentro del poder de PCRE.
fuente
¡Oh, sí, puedes usar expresiones regulares para analizar HTML!
Para la tarea que está intentando, ¡las expresiones regulares están perfectamente bien!
Que es cierto que la mayoría de la gente subestima la dificultad de análisis de HTML con expresiones regulares y por lo tanto hacen tan mal.
Pero este no es un defecto fundamental relacionado con la teoría computacional. Esa estupidez se repite mucho por aquí , pero no les creas.
Entonces, aunque ciertamente se puede hacer (esta publicación sirve como una prueba de existencia de este hecho incontrovertible), eso no significa que deba serlo.
Debes decidir por ti mismo si estás a la altura de la tarea de escribir lo que equivale a un analizador HTML dedicado y de propósito especial a partir de expresiones regulares. La mayoría de las personas no lo son.
Pero yo si . ☻
Soluciones generales de análisis HTML basadas en expresiones regulares
Primero, mostraré lo fácil que es analizar HTML arbitrario con expresiones regulares. El programa completo está al final de esta publicación, pero el corazón del analizador es:
¿Ves lo fácil que es leer?
Tal como está escrito, identifica cada pieza de HTML y le dice dónde encontró esa pieza. Puede modificarlo fácilmente para hacer lo que quiera con cualquier tipo de pieza, o para tipos más particulares que estos.
No tengo fallas en los casos de prueba (izquierda :): he ejecutado con éxito este código en más de 100,000 archivos HTML, cada uno de los cuales pude tener en mis manos rápida y fácilmente. Más allá de eso, también lo ejecuté en archivos construidos específicamente para romper analizadores ingenuos.
Este no es un analizador ingenuo.
Oh, estoy seguro de que no es perfecto, pero aún no he logrado romperlo. Me imagino que incluso si algo sucediera, la solución sería fácil de encajar debido a la estructura clara del programa. Incluso los programas con expresiones regulares deberían tener estructura.
Ahora que está fuera del camino, permítanme abordar la pregunta del OP.
Demostración de cómo resolver la tarea del OP utilizando expresiones regulares
El pequeño
html_input_rx
programa que incluyo a continuación produce el siguiente resultado, para que pueda ver que analizar HTML con expresiones regulares funciona bien para lo que desea hacer:Analizar etiquetas de entrada, ver No hay entrada malvada
Aquí está la fuente del programa que produjo el resultado anterior.
Ahí tienes! Nada de eso! :)
Solo usted puede juzgar si su habilidad con expresiones regulares depende de cualquier tarea de análisis particular. El nivel de habilidad de cada persona es diferente, y cada nueva tarea es diferente. Para los trabajos en los que tiene un conjunto de entrada bien definido, las expresiones regulares son obviamente la opción correcta, porque es trivial juntarlas cuando tiene un subconjunto restringido de HTML con el que lidiar. Incluso los principiantes de expresiones regulares deben manejar esos trabajos con expresiones regulares. Cualquier otra cosa es exagerada.
Sin embargo , una vez que el HTML comienza a ser menos claro, una vez que comienza a ramificarse de maneras que no puede predecir pero que son perfectamente legales, una vez que tiene que hacer coincidir más tipos diferentes de cosas o con dependencias más complejas, eventualmente llegará a un punto donde tiene que trabajar más para lograr una solución que use expresiones regulares de lo que tendría que usar una clase de análisis. Donde cae ese punto de equilibrio depende nuevamente de su propio nivel de comodidad con expresiones regulares.
¿Entonces qué debo hacer?
No voy a decirte lo que debes hacer o lo que no puedes hacer. Creo que eso está mal. Solo quiero presentarte posibilidades, abre los ojos un poco. Puedes elegir lo que quieres hacer y cómo quieres hacerlo. No hay absolutos, y nadie más conoce tu propia situación tan bien como tú. Si algo parece que es demasiado trabajo, bueno, tal vez lo sea. La programación debería ser divertida , ya sabes. Si no es así, puede estar haciéndolo mal.
Uno puede mirar mi
html_input_rx
programa de muchas maneras válidas. Uno de ellos es que de hecho puede analizar HTML con expresiones regulares. Pero otra es que es mucho, mucho, mucho más difícil de lo que casi todos piensan. Esto puede llevar fácilmente a la conclusión de que mi programa es un testimonio de lo que no debe hacer, porque realmente es demasiado difícil.No estaré en desacuerdo con eso. Ciertamente, si todo lo que hago en mi programa no tiene sentido para usted después de algún estudio, entonces no debería intentar usar expresiones regulares para este tipo de tarea. Para HTML específico, las expresiones regulares son geniales, pero para HTML genérico, equivalen a locura. Uso clases de análisis todo el tiempo, especialmente si es HTML que no he generado yo mismo.
Regexes óptimos para problemas de análisis de HTML pequeños , pesimales para problemas grandes
Incluso si mi programa se toma como ilustrativo de por qué usted debe no utiliza expresiones regulares para analizar general de HTML - lo cual está bien, porque un poco decir para que sea de esa ☺ - que todavía debe ser una revelación para que más gente a romper el terriblemente común y desagradable, desagradable hábito de escribir patrones ilegibles, no estructurados e imposibles de mantener.
Los patrones no tienen que ser feos, y no tienen que ser difíciles. Si creas patrones feos, es un reflejo en ti, no en ellos.
Lenguaje fenomenalmente exquisito de expresiones regulares
Me han pedido que señale que mi solución proferida a su problema ha sido escrita en Perl. ¿Estás sorprendido? ¿No te diste cuenta? ¿Es esta revelación una bomba?
Es cierto que no todas las otras herramientas y lenguajes de programación son tan convenientes, expresivos y poderosos cuando se trata de expresiones regulares como Perl. Hay un gran espectro, algunos son más adecuados que otros. En general, es más fácil trabajar con los idiomas que han expresado expresiones regulares como parte del lenguaje central en lugar de como una biblioteca. No he hecho nada con expresiones regulares que no pudieras hacer, por ejemplo, PCRE, aunque estructurarías el programa de manera diferente si usaras C.
Eventualmente, otros idiomas se pondrán al día con Perl en términos de expresiones regulares. Digo esto porque cuando comenzó Perl, nadie más tenía nada como las expresiones regulares de Perl. Di lo que quieras, pero aquí es donde Perl claramente ganó: todos copiaron las expresiones regulares de Perl, aunque en diferentes etapas de su desarrollo. Perl fue pionero en casi (no del todo, pero casi) todo lo que usted ha llegado a confiar en los patrones modernos de hoy, sin importar qué herramienta o lenguaje use. Entonces, eventualmente los demás se pondrán al día.
Pero solo se pondrán al día con Perl en el pasado, tal como es ahora. Todo avanza. En expresiones regulares, si nada más, donde Perl conduce, otros lo siguen. ¿Dónde estará Perl una vez que todos los demás finalmente se pongan al día donde está Perl ahora? No tengo idea, pero sé que nosotros también nos habremos mudado. Probablemente estaremos más cerca del estilo de patrones de elaboración de Perl₆ .
Si te gusta ese tipo de cosas pero te gustaría usarlo en Perl₅, quizás te interese el maravilloso módulo Regexp :: Grammars de Damian Conway . Es completamente increíble, y hace que lo que he hecho aquí en mi programa parezca tan primitivo como el mío hace que los patrones que las personas agrupan sin espacios en blanco o identificadores alfabéticos. ¡Echale un vistazo!
HTML simple Chunker
Aquí está la fuente completa del analizador desde el que mostré la pieza central al comienzo de esta publicación.
Estoy no sugiriendo que usted debe utilizar esta clase de análisis a través de una rigurosa prueba. Pero estoy cansado de que la gente finja que nadie puede analizar HTML con expresiones regulares solo porque no pueden. Claramente puede, y este programa es prueba de esa afirmación.
Está claro que no es fácil, pero que es posible!
Y tratar de hacerlo es una pérdida de tiempo terrible, porque existen buenas clases de análisis que debe utilizar para esta tarea. La respuesta correcta para las personas que intentan analizar HTML arbitrario no es que sea imposible. Esa es una respuesta fácil y falsa. La respuesta correcta y honesta es que no deberían intentarlo porque es demasiado molesto descubrirlo desde cero; no deben romperse la espalda tratando de reinventar una rueda que funcione perfectamente bien.
Por otro lado, el HTML que se encuentra dentro de un subconjunto predecible es muy fácil de analizar con expresiones regulares. No es de extrañar que la gente intente usarlos, porque para problemas pequeños, problemas con los juguetes, tal vez, nada podría ser más fácil. Es por eso que es tan importante distinguir las dos tareas, específicas versus genéricas, ya que estas no requieren necesariamente el mismo enfoque.
Espero en el futuro ver un tratamiento más justo y honesto de las preguntas sobre HTML y expresiones regulares.
Aquí está mi lexer HTML. No intenta hacer un análisis de validación; solo identifica los elementos léxicos. Puede pensarlo más como un fragmentador de HTML que como un analizador de HTML. No es muy indulgente con HTML roto, aunque hace algunas concesiones muy pequeñas en esa dirección.
Incluso si nunca analiza HTML completo usted mismo (¿y por qué debería hacerlo? ¡Es un problema resuelto!), Este programa tiene muchos bits de expresiones regulares geniales de los que creo que mucha gente puede aprender mucho. ¡Disfrutar!
fuente
//input[@type="hidden"]
. O si no desea usar xpath, solo obtenga todas las entradas y filtre con cuáles están ocultasgetAttribute
.Prefiero # 2.
Resultado:
fuente
En el espíritu de la solución léxica de Tom Christiansen, aquí hay un enlace al artículo de 1998 aparentemente olvidado de Robert Cameron, REX: XML Shallow Parsing with Regular Expressions.
http://www.cs.sfu.ca/~cameron/REX.html
Si te gusta leer sobre expresiones regulares, el artículo de Cameron es fascinante. Su escritura es concisa, minuciosa y muy detallada. No solo le muestra cómo construir la expresión regular REX, sino también un enfoque para construir expresiones regulares complejas a partir de partes más pequeñas.
He estado usando la expresión regular REX por intervalos durante 10 años para resolver el tipo de problema sobre el que preguntó el póster inicial (¿cómo hago coincidir esta etiqueta en particular pero no alguna otra etiqueta muy similar? He descubierto que la expresión regular que desarrolló es completamente confiable.
REX es particularmente útil cuando se concentra en los detalles léxicos de un documento, por ejemplo, al transformar un tipo de documento de texto (por ejemplo, texto plano, XML, SGML, HTML) en otro, donde el documento puede no ser válido, bien formado, o incluso analizable para la mayor parte de la transformación. Le permite apuntar a islas de marcado en cualquier lugar dentro de un documento sin alterar el resto del documento.
fuente
Si bien me encantan los contenidos del resto de estas respuestas, en realidad no respondieron la pregunta directamente o tan correctamente. Incluso la respuesta de Platinum fue demasiado complicada y también menos eficiente. Así que me vi obligado a poner esto.
Soy un gran defensor de Regex, cuando se usa correctamente. Pero debido al estigma (y el rendimiento), siempre afirmo que un XML o HTML bien formado debe usar un analizador XML. E incluso un mejor rendimiento sería el análisis de cadenas, aunque hay una línea entre la legibilidad si eso se sale de control. Sin embargo, esa no es la pregunta. La pregunta es cómo hacer coincidir una etiqueta de entrada de tipo oculto. La respuesta es:
Dependiendo de su sabor, la única opción de expresiones regulares que necesitaría incluir es la opción ignorar.
fuente
<input type='hidden' name='Oh, <really>?' value='Try a real HTML parser instead.'>
>
campo de nombre son casi nulas, es posible que haya>
un identificador de acción. Por ejemplo: una llamada de JavaScript en línea en la propiedad OnClick. Dicho esto, tengo un analizador XML para esos, pero también tengo un Regex para aquellos en los que el documento que recibo está demasiado desordenado para que los analizadores XML puedan manejarlo, pero un Regex puede. Además, esta no es la pregunta. Nunca se encontrará con estas situaciones con una entrada oculta, y mi respuesta es la mejor.Ya, <really>!
./>
es un ismo XML; no es obligatorio en ninguna versión de HTML, excepto XHTML (que nunca ganó mucha tracción y ha sido reemplazado por HTML5). Y tiene razón en que hay un montón de HTML desordenado no realmente válido, pero un buen analizador de HTML ( no XML) debería ser capaz de hacer frente a la mayoría; si no lo hacen, muy probablemente tampoco lo harán los navegadores.puedes probar esto:
y para un resultado más cercano puedes probar esto:
puedes probar tu patrón de expresiones regulares aquí http://regexpal.com/
estos patrones son buenos para esto:
y para un orden aleatorio de
type
,name
yvalue
puedes usar esto:o
en este :
``
por cierto creo que quieres algo como esto:
No es bueno, pero funciona de cualquier manera.
pruébalo en: http://regexpal.com/
fuente
Me gustaría usar
**DOMDocument**
para extraer el código html.Por cierto, puedes probarlo aquí: regex101.com. Muestra el resultado en tiempo real. Algunas reglas sobre Regexp: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html Reader .
fuente
suponga que su contenido html está almacenado en una cadena html, para obtener cada entrada que contenga el tipo oculto, puede usar expresiones regulares
el regex anterior se encuentra
<input
seguido de cualquier número de caracteres hasta que se obtienetype="hidden"
o escriba = 'hidden' seguido de cualquier número de caracteres hasta que se obtiene>
/ g le dice a la expresión regular que busque cada subcadena que coincida con el patrón dado.
fuente