JavaScript: reemplace tres espacios con la entidad html 160 después de que XMLSerializer analice incorrectamente las entidades

Estoy tratando de hacer algo como esto ...

f = f.replace('   ','   ','gi');

También he probado esto...

f = f.replace(/\ {3,}/g,'   ','gi');

¿Cómo reemplazo tres espacios con la entidad anterior?

Usar \s no funciona, he pasado por muchas otras preguntas y respuestas en Stack y nada ha funcionado.

Para aclarar este problema se deriva de XMLSerializer() el análisis además de la serialización y los espacios están al comienzo de cada oración. Lo uso para hacer que el código sea legible por humanos al editar.

Ejemplo de texto de marcador de posición en el editor XHTML (solo un área de texto)...

 <p>1
 &#160; 2
 &#160; 3
 &#160; 4
 &#160; 5</p>

... el objetivo es serializar este código y conservar las entidades (la serialización no debe analizar, pero todos los navegadores lo hacen) o "desanalizar" reemplazando los efectos posteriores.

Además, la variable f es una cadena, no un objeto o fragmento en el ejemplo.

IMPORTANTE!

Después de usar encodeURI resulta que estos no son espacios generados por XMLSerializer(), (espacios añadidos para que esto sea más legible) %0A %20 %C2 %A0 %C2 %A0.


Aquí hay un par de ejemplos de cómo se ve el texto antes y después de usar encodeURI para determinar cuáles eran los caracteres, ya que no coincidían con los espacios, lo que desconcertaba a las personas que intentaban ayudar...

%0A%20&#160;&#160;First%20and

&#160;&#160;First and

El primero tiene dos entidades insertadas, no deseable, solo necesito una.

&#160; Which is actually

%0A%20&#160;%20Which%20is%20actually

La segunda salida funciona muy bien usando lo siguiente de @Bergi...

f = f.replace(/\u00a0/g, '&#160;')

Los siguientes son los intentos fallidos, siendo el último el intento exitoso...

//f = f.replace(/^\s+|\s+$/g,'');
//f = f.replace('   ',' &#160; ','gi');
//f = f.replace( / {3,}/g, '&#160;' );
//f = f.replace(/ {3,}/g,' \u00a0 ');
//f = f.replace(/\ {3,}/g,' &#160; ');
f = f.replace(/ \u00a0/g, ' &#160;');

preguntado el 27 de julio de 12 a las 20:07

No replace solo toma 2 parametros? -

¿Qué f ¿parece? -

Deberías usar replace con solo con el dos parámetros estándar. De todas formas, ignorecase no tiene sentido para los espacios en blanco, y su expresión regular ya tiene el global bandera. -

@John Ahora ha editado la pregunta para mostrarnos lo que tienen. Por favor, edítelo también para mostrarnos lo que quieres, como si "si fuera a escribir la fuente HTML sin formato para mi resultado en un editor de texto, ¿qué escribiría?" -

Muéstrenos el código: qué entrada tiene, cómo lo lee en JS y cómo configura la salida (área de texto). -

3 Respuestas

var f = "Hello      World";
f = f.replace( / {3,}/g, '&#160;' );
console.log(f);
// "Hello&#160;World"

Parece que su problema no tiene nada que ver con el reemplazo de la cadena, sino con la forma en que lo está usando para modificar su HTML. ¿Qué estás haciendo para eso?

Editar: Si desea que el usuario realmente ver &#160; en el navegador, entonces necesitas:

f = f.replace( /\s+{3,}/g, '&amp;#160;' );

Demostración: http://jsfiddle.net/wrMMy/

Respondido 27 Jul 12, 21:07

@John Está bien, genial. Así que lo que están ¿haces? - Phrogz

Lo intenté, lo siento, no hay dados. Tenga en cuenta que los espacios están al principio después de un salto de línea y no en medio del texto. - John

@ John, te acabo de mostrar que esto funciona. Su problema radica fuera de su reemplazo de cadena, y lo que está "Hacer" con eso. Esto es lo que necesitamos saber para ayudarte. ¿Cuál es su código real para usar? f después del resultado? - Phrogz

Muy bien, he actualizado esto. Me encontré con este problema antes al intentar escribir directamente en el DOM y lo solucioné trabajando con una cadena. La cosa es variable f IS una cadena, así que no estoy seguro de cómo si f es una cadena para comenzar y luego recibir el código y luego, en tercer lugar, hacer que regex funcione (el código de Hugo funciona en jsfiddle pero no en mi código) significa que algo está mal. - John

@ John Hugo funciona porque está viendo el contenido de la cadena en un cuadro de alerta, donde HTML no se interpreta. si escribiste alert('<b>hi</b/>') no aparecería en negrita, vería el marcado. De manera similar, cuando alertas a la cadena "&#160;" ves la entidad. Sin embargo, cuando inyecta esa cadena en el navegador web como HTML, se convierte en un carácter de espacio en blanco invisible. - Phrogz

En lugar de reemplazar con una entidad, reemplace con el carácter real:

 f = f.replace(/ {3,}/g,' \u00a0 ');

Por supuesto, eso depende de la salida de esa cadena, pero generalmente debe usar una cadena como debe ser.

Por cierto: para hacer legibles los espacios en blanco html/xml, recomendaría la propiedad css white-space:pre-wrap en lugar de insertar caracteres que no se rompen. Especialmente hacen que copiar el texto sea un horror. Además, si su deseo es mostrar tantos espacios en blanco como en la fuente, debe reemplazar /\s{2}/ con " \u00a0".


OK, tienes una entrada muy curiosa: linebreak (10, %0A, "\n"), un espacio normal (32, %20, " ") y dos espacios de no separación (160, %C2%A0, "\u00a0"). Lo que podría hacer ahora para obtener el resultado deseado:

  • reemplace el primer nbsp con su entidad y el segundo con un espacio en blanco: replace(/\u00a0{2}/g, "&#160; ")
  • reemplace solo el primero de dos nbsp adyacentes: replace(/\u00a0(.)/g, "&#160;$1")
  • reemplace tres espacios en blanco con dos espacios en blanco y una entidad entre: replace(/\s{3}/g, " &#160; ")

Respondido 27 Jul 12, 22:07

Eso haría lo contrario de lo que estoy tratando de hacer. - John

¿Qué es exactamente están estás tratando de hacer? ¿Quieres mostrarle al usuario un montón de entidades? - Bergi

Las oraciones se escriben correctamente con dos espacios entre ellas. Para la edición legible por humanos, uso un salto de línea y luego [espacio][entidad 160][espacio]. - John

¿Y qué es exactamente lo que no funciona? ¿Cómo establece el valor de su editor textarea? - Bergi

Entonces tu quieres replace(/\u00a0/g, "&#160;")? - Bergi

f = f.replace(/\ {3,}/g,' &#160; ');

Eso funciona. replace toma sólo dos argumentos.
Demostración: http://jsfiddle.net/SjydF/

Respondido 27 Jul 12, 21:07

No es necesario escapar del espacio en la expresión regular. - Phrogz

Eso funciona allí pero no en mi código. La variable f es una cadena y no un fragmento, aunque proviene de la serialización. - John

El uso de encodeURI resulta que estos no son espacios (se agregaron espacios para que sea más legible) %0A %20 %C2 %A0 %C2 %A0. Tenga en cuenta que esto es de la salida de serialización. - John

Votar a favor, estaba en el tema antes de que mencionara la serialización. - John

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.