2010-11-30 10 views
5

He estado jugando con esto durante una hora o remolque y me he encontrado en un bloque de carreteras con las utilidades de comparación de patrones de Lua. Estoy intentando hacer coincidir todo el texto citado en una cadena y reemplazarlo si es necesario.¿Cuál es el patrón de Lua adecuado para el texto entre comillas?

El patrón que he subido con hasta ahora es: (\ [\ "\ ']?) (.-) 1%

Esto funciona, pero en algunos casos, no todos los casos:

Working: "This \"is a\" string of \"text to\" test with" 

Not Working: "T\\\"his \"is\' a\" string\" of\' text\" to \"test\" wit\\\"h" 

En el ejemplo que no funciona me gustaría que coincida con (hice una función que obtiene las coincidencias que deseo, estoy buscando un patrón para usar con gsub y curioso si un patrón de lua puede hacer esto):

string 
a" string" of 
is' a" string" of' text 
test 
his "is' a" string" of' text" to "test" wit 

Voy a continuar por el momento, uso mi función, pero tengo curiosidad por saber si hay un patrón que podría/debería estar usando y me falta algo con los patrones.

(unas pocas ediciones b/c me había olvidado de stackoverflows formateo) (otra edición para hacer un ejemplo no html ya que estaba dando lugar a suposiciones de que yo estaba tratando de analizar HTML)

+0

posible duplicado de [RegEx cerró las etiquetas abiertas, excepto las etiquetas autocontenidas XHTML] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) –

Respuesta

5

Intentar hacer coincidir texto escapado y citado usando expresiones regulares es como tratar de eliminar las margaritas (y solo las margaritas) de un campo usando una cortadora de césped.

Hice una función que obtiene los partidos deseo

Este es el movimiento correcto.

Tengo curiosidad por si un patrón lua puede hacer esto

Desde un punto de vista práctico, incluso si un patrón se puede hacer esto, usted no desea. Desde un punto de vista teórico, está tratando de encontrar una comilla doble precedida por un número par de barras diagonales inversas. Esto es definitivamente un lenguaje regular, y la expresión regular que desee sería algo así como los (convenciones Lua citando a) siguiente

[[[^\](\\)*"(.-[^\](\\)*)"]] 

Y la cadena entre comillas sería resultado # 2. Pero los patrones de Lua son no expresiones regulares completas; en particular, no puede poner un * después de un patrón entre paréntesis. Así que Supongo que este problema no se puede resolver usando patrones de Lua,, pero como los patrones de Lua no son una característica estándar en la teoría de autómatas, no conozco ningún conjunto de técnicas de prueba que pueda usar para probarlo.

+0

Gracias tanto a Norman como a Kevin, exactamente las respuestas que estaba esperando y buscando. – Wolftousen

0

que debiera NO intente analizar HTML con expresiones regulares, HTML y XML son NO idiomas normales y no se pueden manipular con éxito con expresiones regulares. Deberías usar un analizador de HTML dedicado. Here are lots of explanations why.

+0

No podía descuidar el html, era solo mi cadena de prueba que agarré de un archivo aleatorio que tenía abierto. Lo único que me importa son las comillas – Wolftousen

+0

, entonces sugeriría usar un ejemplo que no sea HTML y eliminar esa ambigüedad –

+0

¿Tratas '' 'y' "' por igual como comillas? De ser así, ¿cómo esperarías que tu ejemplo 'no funcionara'? para ser analizados? Por ejemplo, '" es 'una "cadena" de' texto ''contiene comillas superpuestas. Se supone que debemos encontrar' "es' un '' y' 'de 'texto' ', o'' una "cadena" de ', o las tres? Si es la última, vas a tener que hacer eso en dos pasadas. – Mud

2

El problema con las comillas que se escapó es que, en general, si hay un número impar de barras diagonales inversas antes de la cita, entonces se escapó, y si hay un número par, no lo es. No creo que la coincidencia de patrones de Lua sea lo suficientemente poderosa como para representar esta condición, por lo que si necesita analizar un texto como este, entonces debe buscar otra forma. Tal vez puedas iterar a través de la cadena y analizarlo, o podrías encontrar cada cita por turno y leer hacia atrás, contando las barras invertidas hasta que encuentres un carácter que no sea de barra invertida (o el comienzo de la cadena).

Si tiene que usar patrones por alguna razón, puede intentar hacerlo en un proceso de varios pasos. Primero, gsub para todas las ocurrencias de dos barras diagonales inversas en una fila, y reemplácelas con algún valor centinela. Este debe ser un valor que ya no aparece en la cadena. Podría intentar algo como "\ 001" si sabe que esta cadena no contiene caracteres no imprimibles. De todos modos, una vez que haya reemplazado todas las secuencias de dos barras invertidas en una fila, las barras invertidas restantes se escapan del siguiente carácter. Ahora puede aplicar su patrón original, y finalmente puede reemplazar todas las instancias de su valor centinela con dos barras invertidas nuevamente.

+0

Quizás LPeg podría manejarlo? http://www.inf.puc-rio.br/~roberto/lpeg/lpeg. html –

1

El lenguaje de patrones de Lua es adecuado para muchos casos simples. Y tiene al menos un truco que no encuentras en un paquete típico de expresiones regulares: una forma de unir paréntesis equilibrados. Pero también tiene sus límites.

Cuando se exceden esos límites, alcanzo el LPeg. LPeg es una implementación de un Parsing Expression Grammer para Lua, y fue implementado por uno de los autores originales de Lua, por lo que la adaptación a Lua se realiza bastante bien. Un PEG permite escribir cualquier cosa, desde patrones simples hasta gramáticas de lenguaje completas. LPeg compila la gramática en un bytecode y la ejecuta de manera extremadamente eficiente.

Cuestiones relacionadas