Investigue y reemplace Word Rtf

Estoy trabajando en una aplicación que tiene un flujo de trabajo para correos postales. Estos correos postales se generan según las reglas comerciales de mi aplicación.

Los modelos están en html o Rtf y funcionan perfectamente siempre que el usuario no cree el rtf con la palabra. Esto no está dentro de las especificaciones, pero mi jerarquía daría la bienvenida a una compatibilidad de Word si no implica demasiado trabajo, y sería agradable y facilitaría la vida de nuestro cliente.

Los modelos Rtf tienen tags que se reemplazan por valores de aplicación. En la mayoría de los RTF, las tags no se dividen, por lo que la búsqueda y el reemplazo funcionan perfectamente. Deseo ser manejado con algunas modificaciones.

Datos de ejemplo: [[FooBuzz]] en la mayoría de los RTF no está dividido.

En palabra 2003:

{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 FooBuzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]} 

Y su palabra (palabra 2007) se dividió también Foo {basura dentro} Buzz.

Así que deseo ser capaz de manejar RTF común perfectamente, y detectar tags incluso si están divididas.

Tengo 2 restricciones. Primero no hay regresión, segundo tiene que ser simple. El rendimiento no es un problema aquí.

Estoy usando Symfony 1.4. La parte del código de investigación relevante real:

 $regExpression = '/\[\[([^\[\]]*)\]\]/'; preg_match_all($regExpression, $sTemplate, $outKeys); 

Actualización:

Creo que principalmente necesito perfeccionar esta expresión regular. Estoy trabajando en algunas expresiones regulares, pero aún necesitan algunas mejoras:

 /([\a-zA-Z0-9]+)/ 

Produce :

 [0] => Array ( [0] => \rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[ [1] => \rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 FooBuzz [2] => \rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]] ) 

Actualización 2:

Todavía tengo algunos problemas con la expresión regular. En realidad, encuentra el valor de la etiqueta y el texto sin formato para la primera. No estoy seguro de que lo que quiero sea posible incluso en un tiempo razonable.

Necesito modificar la expresión regular, por lo que ella capta los mismos resultados, pero dentro de [[]], en realidad también funciona en texto plano.

Y aún más difícil tengo que poder capturar todos mis datos de muestra (pero no texto plano) por lo que sea necesario.

Para mi reemplazar regex, que reemplaza mi etiqueta y toda la basura. Casi he tenido éxito:

 /{.*?\[\[.*(?<!\\)\w+\b.*\]\].*?}/ 

Pero es demasiado codicioso. Quiero hacer coincidir el grupo {[[} {tag} {]]} y coincide {plain text} {[[} {tag} {]]} {plain text}

Agrego el? porque lo leí haría que el. * no codicioso, pero no funciona. Algunas ideas ?

No puedo obtener lo que está mal con esta expresión regular (nombre de búsqueda de etiqueta):

 \[\[(\b(?<!\\)\w+\b)\]\] 

De acuerdo con mi entendimiento. Dice dentro de [[]], encuentra cualquier palabra que no comience con un backslawh seguido de cualquier carácter de palabra. Estoy en lo correcto?

Actualización 3:

Lo siento, no estaba claro.

Mi primer objective regex es capturar FooBuzz en [[FooBuzz]]. Y el segundo para atrapar a [[FooBuzz]]. Entonces, en la primera expresión regular, quiero capturar solo el texto FooBuzz e ignorar todo lo demás (como {} \ eoeoe).

En segundo lugar, tengo que reemplazar [[FooBuzz]] por completo. Así que tengo que atrapar {[[} {FooBuzz}} {]]} y nada más.

De hecho, estoy atrapando {texto sin formato que no capturo} {[[} {FooBuzz}} {]]}}. Vea que yo también debo capturar aquí. Estoy capturando: texto sin formato que no capturo [[FooBuzz]].

Para la [[parte, solo necesito capturar esto: {\ rtlch \ fcs1 \ af0 \ ltrch \ fcs0 \ insrsid5517131 [[}. Supongo que es porque no puede encontrar una pareja sin sangre. Entonces él está en modo codicioso. Y falla con esta muestra de datos:

 {\toto toto}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 FooBuzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]}{\toto toto} 

Después de su edición, para encontrar FooBuzz o cualquier otra etiqueta, puede buscar

 (?<=\[\[).+?\b(? 

y unir el primer grupo.

Encuentra una palabra completa no precedida de un \ using lookbehind negativo (? también para indicar que debe ir precedida por [[ y seguido por ]]

Aquí un ejemplo, puedes ver el primer grupo que contiene correctamente FooBar 🙂

Para entender mejor RTF encontré un buen enlace , creo que también podría considerar un enfoque no regex, incluso si en este caso no tengo pistas.

EDITAR:

Su última expresión regular es incorrecta porque espera una \w+ exactamente después del último corchete, solo coincidirá con algo como [[wordWithoutSpaces]] .

La primera expresión regular "actualización 1" coincide correctamente con toda la cadena, dices: "comienza en la primera { y encuentra bastante todo". Veamos:

  • {.*?\[\[ coincide con todo entre { y [[
  • .*(? coincide todo después de que [[ y antes del carácter de la primera palabra \w no precedido por una barra diagonal inversa (probablemente aquí quiera a \b antes del aspecto negativo detrás y el \w )
  • .*\]\].*?}/ coincidir todo entre ]] y el primero } encontrar (no codicioso)

Pero si desea hacer coincidir las partes individuales, necesita crear diferentes coincidencias o diferentes grupos

EDITAR :

Como solo una expresión regular es posible fusionar las dos expresiones regulares creadas en esta respuesta:

 {[^{]?[[.(?<=[[).+?\b(?]].?} 

Preg_match_all devolverá 2 tabs. 1 que contiene los datos que coinciden con la expresión regular, el segundo la etiqueta.

Y luego, gracias a la función strtr, solo se reemplazan las tags que coinciden con las traducciones. (3 rondas en el flujo de trabajo).

En caso de que algunas personas tengan el mismo problema. Una solución mejor y global. La representación de palabras de RTF depende de … policía. Así que una búsqueda de texto simple de [[FooBuzz]] en tiempos de nuevas obras romanas. Pero en Arial, la palabra explota, y necesitas una expresión regular inteligente.

Ejemplos:

 Police Text RTF Times new roman [[FooBuzz]] {\someRtfTags [[FooBuzz]]} Arial [[FooBuzz]] {\hich\af1\dbch\af12\loch\f1 [[Signature}{\rtlch\fcs1 \af0 \ltrch\fcs0 \i\insrsid15225063 \hich\af1\dbch\af12\loch\f1 President}{\rtlch\fcs1 \af0 \ltrch\fcs0 \i\insrsid1974114\charrsid1974114 \hich\af1\dbch\af12\loch\f1 ]]} 

Entonces usa Times new Roman para las tags.