Forzando el caballo

8

Este es simple: cree el script de navegador más corto para cambiar cada aspecto de fuerza en una página web a caballo. Este script debe poder pegarse en la consola y funcionar en la mayoría de los navegadores modernos.

Debe reemplazar todas las ocurrencias de la palabra fuerza y ​​conjugados de la palabra fuerza (forzar, forzar, reforzar). Los casos también deben ser preservados.

No debe cambiar ninguna ocurrencia que no sea visible cuando la página se muestra en un navegador. Por ejemplo, metaetiquetas o comentarios.

Ejemplo

Se trata de una fOrcE log. Hace que las personas que lo tocan sean muy contundentes. No intentes forzarlo.

Se trata de una hOrsE log. Hace que las personas que lo tocan sean muy pesadas. No trates de adorarlo.

Desafortunadamente, este es un desafío solo de Javascript. El código más corto gana.

Decaimiento Beta
fuente
2
Lol para xkcd XD
ThreeFx
99
forzar no contiene la palabra fuerza .
Dennis
2
O la pregunta permite el reemplazo de forcinto hors- o es el reemplazo de todas las diferentes conjugaciones de forceinto sus versiones de caballo. En el primer caso, obtenemos cosas como "Reinhorsing", etc. En el segundo, solo forcingsería una excepción. OP debe aclarar.
absenta
2
¿Qué pasa con los equivalentes equinos de forzar , forzadamente , fórceps ...?
Sean Latham
2
"... cualquier ocurrencia que no sea visible cuando la página se muestra en un navegador". Es demasiado general. En particular, hay docenas o incluso cientos de formas diferentes de insertar contenido no visible en las páginas web. Quizás debería limitar la exclusión a uno o dos tipos específicos de etiqueta. Esto evita .innerHTMLlas soluciones de reemplazo total, lo que supongo que es la razón por la que desea las excepciones en primer lugar.
COTO

Respuestas:

5

175 bytes, ES5, XPATH

Esto prueba con éxito en los últimos Firefox y Chrome. La crítica es bienvenida! Este es mi primer swing de golf, y espero hacerlo bien.

d=document,f=d.evaluate('//text()',d,{},7,{});for(i=0;t=f.snapshotItem(i++);)t.data=t.data.replace(/(f)(or)(c)/ig,function(a,b,c,e){return(b=='f'?'h':'H')+c+(e=='c'?'s':'S')})

El document.evaluate()método es compatible con todos los principales navegadores, excepto IE , que espero satisfaga el requisito de "la mayoría de los navegadores modernos". Y debido a que el selector XPath selecciona solo nodos de texto , esto debería dejar atributos, comentarios, espacios de nombres y otros datos que no están destinados a mostrarse intactos sin necesidad de verificar cada nodo offsetParent.

Versión sin golf:

var force = document.evaluate('//text()', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

for (var i = 0; textNode = force.snapshotItem(i++); /* nothing */) {
    textNode.data = textNode.data.replace(
        /(f)(or)(c)/ig,
        function (full, $1, $2, $3) {
            return ($1 == 'f' ? 'h' : 'H' )
                + $2
                + ($3 == 'c' ? 's' : 'S' );
        }
    );
}

O si lo reemplazo function / returncon la notación de flecha gruesa ECMA6, puedo reducirlo a 163 caracteres.

d=document,f=d.evaluate('//text()',d,{},7,{});for(i=0;t=f.snapshotItem(i++);)t.data=t.data.replace(/(f)(or)(c)/ig,r=(a,b,c,e)=>(b=='f'?'h':'H')+c+(e=='c'?'s':'S'))

Sin embargo, esta sintaxis actualmente solo funciona en Firefox, creo. Hasta que más navegadores adopten esta sintaxis, la solución de 175 bytes anterior seguirá siendo mi entrada oficial para el juego.

rojo
fuente
Enfoque muy interesante! Hay dos diferencias entre nuestras respuestas (la respuesta que se está comportando correctamente es para que la OP la juzgue): 1. Su expresión regular convertirá FORC en HORS . 2. Su código modifica todos los nodos de texto, mientras que verifica offsetParentfiltrar todas las etiquetas con display:noneestilo (que no se muestran en el navegador).
Dennis
@ Dennis Gracias! Sí, puedo agregar (?=e|ing)a mi expresión regular si OP lo considera necesario. Al respecto display: none, interpreté "Por ejemplo, metaetiquetas o comentarios". para significar cosas que no son nodos de texto deben dejarse solos, mientras que los nodos de texto, incluidos los nodos invisibles, deben cambiarse. Sin embargo, me interesaría ver que el OP confirmara sus intenciones.
rojo
@rojo Sí, lo interpretaste correctamente
Beta Decay
3

ECMAScript 5, 248 233 193 191 182 bytes

for(w=(d=document).createTreeWalker(d,4);t=w.nextNode();)
if(t.parentNode.offsetParent)t.data=t.data.replace(/(f)(or)(c)/gi,
function(a,b,c,d){return(b<'f'?'H':'h')+c+(d<'c'?'S':'s')})

Probado en Chrome y Firefox.

Versión sin golf

Solo debemos modificar TextNodes visibles; Las URL, los atributos, etc. no se muestran en el navegador. Podemos usar un TreeWalker para encontrarlos a todos. Los TextNodes visibles se identificarán verificando si su ParentNode tiene un offsetParent verdadero . 1

// Create a TreeWalker that walks through all TextNodes. 

var walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT, null, false);

// While there are nodes left,

while(node = walker.nextNode())

// if the node is visible,

    if(node.parentNode.offsetParent)

// search for the string "forc" (ignoring case)

        node.data = node.data.replace(/(f)(or)(c)/gi,

// and replace an uppercase/lowercase F/C with an uppercase/lowercase H/S.

            function(match, F, OR, C)
            {
                return (F != 'f' ? 'H' : 'h') + OR + (C != 'c' ? 'S' : 's')
            }
)

1 Esto tiene errores en IE 9.

Dennis
fuente
Sabes, puedes bajar esto a 193 bytes si te deshaces de n=[],c=0,poblar y luego volver a recorrerlo n. Just do if(t.parentNode.offsetParent)t.data=t.data.replaceetc.
rojo
2

200 bytes, ES6

Aquí hay una versión ES6. Ejecútelo en la última consola web de Firefox.

for(a=document.all,i=0;n=a[i++];)(p=>p&&p.offsetParent?n.innerHTML=n.innerHTML.replace(/f[o0]rc(e|ing)/gi,m=>(v=>{k=[...m];k[0]=k[0]<'F'?'H':'h';k[3]=k[3]<'C'?'S':'s'})()||k.join("")):0)(n.parentNode)

Agregaré la versión sin golf si así lo solicita :)

Aquí está la versión sin golf

var all = document.all;
for (var i = 0; i < all.length; i++) {
  if (all[i].parentNode && all[i].parentNode.offsetParent) {
    all[i].innerHTML = all[i].innerHTML.replace(/f[o0]rc(e|ing)/gi, function(matched) {
      var k = matched.split(""); // convert to array
      k[0] = k[0] == "F"? "H" : "h";
      k[3] = k[3] == "C"? "S" : "s";
      return k.join("");
    })
  }
}
Optimizador
fuente
1
Solicito una versión sin golf = P
flawr
Wow ... pensé que estas serían frases divertidas ... más o menos replace('forc','hors')y eso es todo. Muestra cuánto javascript sé ...
Beta Decay
1
1. Este enfoque no funciona. innerHTMLcambiará todas las ocurrencias dentro de los elementos visibles, por lo que si hay un comentario dentro, también se tocará. 2. Se podría argumentar que ES6 realmente no funciona en la mayoría de los navegadores modernos .
Dennis
Como dice Dennis anteriormente, esto no cumple con todos los requisitos, por lo tanto, no he aceptado esta respuesta.
Beta Decay