2009-06-05 10 views
16

Tengo algunas dificultades con una Regex específica que estoy tratando de usar. Estoy buscando cada aparición de una cadena (para mis propósitos, diré que es "mystring") en un documento, EXCEPTO donde está en una etiqueta, p.Usa la expresión regular para encontrar una cadena específica que no está en la etiqueta html

<a href="_mystring_"> 

no debería coincidir, pero

<a href="someotherstring">_mystring_</a> 

debe coincidir, ya que no es dentro de una etiqueta (en el interior significado "dentro del < y> marcadores") estoy usando funciones de expresiones regulares de .NET para este también.

+0

¿quiere decir su segundo ejemplo debería * no * coincidir? –

+5

[Insertar "no usar expresiones regulares para analizar HTML" aquí] –

+1

robbotic: no, debe coincidir. No está dentro de los marcadores < and >. Necesito hacer un reemplazo en _mystring_ pero no cuando es parte de la etiqueta, ya que está en el primer ejemplo. Además, cargar esto en un XDocument o lo que no es realmente posible en mi situación. – Sukasa

Respuesta

17

Esto debe hacerlo:

(?<!<[^>]*)_mystring_ 

Utiliza un aspecto negativo tras comprobar que la cadena coincidente no tiene un < antes de que sin la correspondiente>

+0

Aunque Necesitaba algunas reglas más para mejorar mi aspecto y para mis necesidades específicas, esto es lo que hizo que las cosas funcionen para mí. ¡Gracias! – Sukasa

+1

¡Guau, esa es una hermosa expresión regular! @Sukasa, ¿puedes publicar el último que se te ocurrió? – travis

+1

No funciona con PHP aunque –

0

¿Por qué usar regex?

Para xhtml, cárguelo en XDocument/XmlDocument; para (no-x) html, el paquete Html Agility parecería una opción más sensata ...

De cualquier forma, eso analizará el html en un DOM para que pueda iterar sobre los nodos e inspeccionarlos.

0

Las búsquedas de expresiones regulares generalmente no son una buena idea en XML. Es muy fácil tener problemas con expresiones de búsqueda que coinciden con mucho o muy poco. También es casi imposible formular una expresión regular que pueda identificar y manejar correctamente las secciones CDATA, las instrucciones de procesamiento (PI) y las secuencias de escape que permite XML.

A menos que tenga completo control sobre el contenido XML que está obteniendo y puede garantizar que no incluirá dichos constructos (y no cambiará), le aconsejaría usar un analizador XML de algún tipo (XDocument o XmlDocument en .net, por ejemplo).

Habiendo dicho eso, si todavía está intentando usar regex como su mecanismo de búsqueda, algo como lo siguiente debería funcionar usando la clase RegEx en .NET. Es posible que desee test it out con algunos de sus propios casos de prueba en un sitio como Regexlib. También es posible que pueda buscar en su catálogo de expresiones regulares para encontrar algo que se ajuste a sus necesidades.

[>]. (_mystring_). [<]

0

ignorando que hay otras maneras de hecho, y que no soy un experto expresiones regulares real, pero una cosa que me vino a la cabeza fue:

  • encontrar todos los mystring s que están en las etiquetas primero - porque no puedo escribir la expresión que hacer lo contrario :)
  • cambio los que a otra cosa
  • continuación, reemplace todo otro mystring (que no se queda en las etiquetas) como sea necesario
  • la restauración original mystring s que estaban en las etiquetas

Por lo tanto, el uso de se pueden encontrar los etiquetados queridos. Reemplace las que tengan otras cadenas. ¿Es normal reemplazar en el mystring s que quedan.Reemplazar otherstring de nuevo a mystring

crudo pero efectivo .... tal vez.

2

Una alternativa rápida y sucia es utilice una función de reemplazo de expresiones regulares con devolución de llamada para codificar el contenido de las etiquetas (todo entre < y>), por ejemplo, utilizando base64, luego ejecute su búsqueda y luego ejecute otra devolución de llamada para decodificar los contenidos de su etiqueta.

Esto también puede ahorrar una gran cantidad de rascarse la cabeza cuando se necesita para excluir etiquetas específicas partir de una búsqueda de expresiones regulares - primera ofuscar ellos y envolverlos en un marcador que no coincidirá con su búsqueda, a continuación, ejecutar la búsqueda, a continuación, desofuscar lo que está en los marcadores.

7

Cuando el procesador de expresiones regulares no soporta mirada detrás de longitud variable, intente esto:

(<.+?>[^<>]*?)(_mystring_)([^<>]*?<.+?>) 

Preserve capture los grupos 1 y 3 y reemplace el grupo de captura 2:

Por ejemplo, en Eclipse, encontrará:

(<.+?>[^<>]*?)(_mystring_)([^<>]*?<.+?>) 

y sustituir por:

$1_newString_$3 

(Otros procesadores de expresiones regulares puede utilizar una sintaxis grupo de captura diferente, como \ 1)

+0

Esta es la respuesta que necesita usar en PHP, encontré ... eventualmente. –

Cuestiones relacionadas