Coincidencia de mayúsculas y minúsculas Buscar Reemplazar


14

Tome tres entradas, una cadena de texto T; una cadena de caracteres para reemplazar F; y una cadena de caracteres para reemplazarlos con R,. Para cada subcadena de Tcon los mismos caracteres (sin distinción entre mayúsculas y minúsculas) que F, reemplácelos con los caracteres en R. Sin embargo, mantenga el mismo caso que el texto original.

Si hay más caracteres en Rque F, los caracteres adicionales deben ser el mismo caso, ya que están en R. Si hay números o símbolos adentro F, entonces los caracteres correspondientes Rdeben mantener el caso en el que están R. Fno necesariamente aparecerá en T.

Puede suponer que todo el texto estará en el rango ASCII imprimible.

Ejemplos

"Text input", "text", "test" -> "Test input"

"tHiS Is a PiEcE oF tExT", "is", "abcde" -> "tHaBcde Abcde a PiEcE oF tExT"

"The birch canoe slid on the smooth planks", "o", " OH MY " -> "The birch can OH MY e slid  OH MY n the sm OH MY  OH MY th planks"

"The score was 10 to 5", "10", "tEn" -> "The score was tEn to 5"

"I wrote my code in Brain$#@!", "$#@!", "Friend" -> "I wrote my code in BrainFriend"

"This challenge was created by Andrew Piliser", "Andrew Piliser", "Martin Ender" -> "This challenge was created by Martin Ender"

// Has a match, but does not match case 
"John does not know", "John Doe", "Jane Doe" -> "Jane does not know"

// No match
"Glue the sheet to the dark blue background", "Glue the sheet to the dark-blue background", "foo" -> "Glue the sheet to the dark blue background"

// Only take full matches
"aaa", "aa", "b" -> "ba"

// Apply matching once across the string as a whole, do not iterate on replaced text
"aaaa", "aa", "a" -> "aa"

"TeXT input", "text", "test" -> "TeST input"

Enlace de caja de arena


Solicitando un ejemplo con una carcasa extraña:"TeXT input", "text", "test"
Engineer Toast

@EngineerToast Ejemplo agregado
Andrew

No estoy seguro de por qué me pareció "The birch canoe slid on the smooth planks", "o", " OH MY "tan gracioso, pero me encantó ese ejemplo.
Urna mágica de pulpo

Respuestas:


3

Retina , 116 bytes

i`(.+)(?=.*¶\1(¶.*)$)|.*¶.*$
¶¶$2¶$1¶¶
{T`l`L`¶¶.(?=.*¶[A-Z])
T`L`l`¶¶.(?=.*¶[a-z])
}`¶¶¶(.)(.*¶).
$1¶¶¶$2
¶¶¶¶.*|¶

Pruébalo en línea! Explicación:

i`(.+)(?=.*¶\1(¶.*)$)|.*¶.*$
¶¶$2¶$1¶¶

Esto busca Ty cada vez que hay una coincidencia entre mayúsculas y minúsculas contra la búsqueda anticipada, Fla coincidencia se rodea de un montón de nuevas líneas y la búsqueda anticipada Rtambién se inserta.

{T`l`L`¶¶.(?=.*¶[A-Z])
T`L`l`¶¶.(?=.*¶[a-z])
}`¶¶¶(.)(.*¶).
$1¶¶¶$2

Cada letra de la copia de Rse ajusta en caso de que coincida con la de la coincidencia, después de lo cual se mueve fuera del área de trabajo para que se pueda procesar la siguiente letra, hasta que la copia Ro la coincidencia se quede sin letras.

¶¶¶¶.*|¶

Si la copia de se Rqueda sin letras, el resto del partido estará precedido por 4 líneas nuevas, así que bórrelo. De lo contrario, todo lo que quede serán piezas sobrantes de copias de las Rcuales deben concatenarse con las partes no coincidentes de la entrada para producir el resultado.


3

APL (Dyalog) , 75 73 72 bytes

Indicaciones para T, Ry Fen ese orden. Rdebe darse en formato de transformación Dyalog yF debe darse en formato PCRE.

⍞⎕R(⍞∘{(⊣⌿d)l¨⍨(1∘⌷≠(⊢⌿d∊⎕A,lA)∧≠⌿)d≠(l819⌶)d←↑⍺⍵.Match↑¨⍨≢⍺})⍠1⊢⍞

Pruébalo en línea!

 solicitar T

 rendimiento que (separa 1 y T )

⍞⎕R(... )⍠1 prontas para Fy R partidos EColoque con el resultado de la siguiente función:

⍞∘{…} deriva una función monádica al vincular el Rargumento solicitado como izquierdo a:

  ≢⍺ cuenta el número de letras en R

  ⍺⍵.Match↑¨⍨ tome esa cantidad de letras de cada una Ry la coincidencia
   es el argumento de la izquierda, que vinculamos Rcomo.
   es un espacio de nombres en el que Matchcontiene la cadena encontrada actualmente.

   mezclar esos dos en una matriz de dos filas

  d← almacenar como d

  (...)   Aplica la siguiente función tácita a eso:

   819⌶ minúscula (mnemónica: 819 parece grande )

   l← almacenar esa función como l

  d≠ Booleano donde d difiere (es decir, da 0/1 para cada letra minúscula / mayúscula)

  () Aplica la siguiente función tácita a eso:

   ≠⌿ XOR vertical

   (... )∧ booleano Y con la siguiente matriz:

    l⎕AUn alfabeto en  minúsculas

    ⎕A,anteponer un alfabeto en  mayúscula A

    d∊ Booleano para cada letra en d si un miembro de eso (es decir, si una letra)

    ⊢⌿ última fila, es decir, para el carácter del partido, ya sea una letra

   1∘⌷≠ XOR con la primera fila, es decir, si cada carácter de Res mayúscula

  ()l¨⍨ Use eso en minúsculas (si es 0) o en mayúsculas (si es 1) cada letra de:

   ⊣⌿ la primera fila, es decir R


* Recuento de bytes para Dyalog Classic usando en ⎕OPT lugar de .



2

Retirado. La respuesta de Dom es mucho mejor.

# Perl 5 , 136 + 1 (-p) = 137 bytes

$f=<>;chomp$f;@R=($r=<>)=~/./g;for$i(/\Q$f/gi){$c=$n='';$"=$R[$c++],$n.=/[A-Z]/?uc$":/[a-z]/?lc$":$"for$i=~/./g;s/\Q$i/$n.substr$r,$c/e}

Pruébalo en línea!

hizo un gran corte después de que @Dom Hastings mencionara \Q

# Perl 5 , 176 + 1 (-p) = 177 bytes

sub h($){chomp@_;pop=~s/[^a-z0-9 ]/\\$&/gir}$f=h<>;@R=($r=<>)=~/./g;for$i(/$f/gi){$c=$n='';$"=$R[$c++],$n.=/[A-Z]/?uc$":/[a-z]/?lc$":$"for$i=~/./g;$i=h$i;s/$i/$n.substr$r,$c/e}

Pruébalo en línea!


Pasa todos los casos de prueba ahora;) 108: ¡ Pruébelo en línea!
Dom Hastings

Deberías publicarlo. Le gana a la mía bastante.
Xcali

¡Lo suficientemente justo! Fue divertido hacerlo. ¡Disfruto el desafío!
Dom Hastings

2

PowerShell , 190 bytes

param($T,$F,$R)[regex]::Replace($T,'(?i)'+[regex]::escape($F),{param($m)-join(0..$R.Length|%{(($y=$R[$_]),("$y"."To$((('Low','Upp')[($z="$m"[$_])-cmatch($C='[A-Z]')]))er"()))[$z-match$C]})})

Pruébalo en línea!

Explicación:

[Regex]::Replace( 
    input text T,
    Find text F with case insensitive and [regex]::escape() for symbols,
    {scriptblock} for computing the replacement
)

El bloque de script de reemplazo hace:

$m is the matched text with case information
loop over each character in R as $y
    $z is the same index character in $m ($null if R overruns)
    $z-match'[A-Z]' checks if alphabetic, so we must to case-match
      otherwise, non-alphabetic or null, no case-match, return $y unchanged.
    if case-matching, check if z case-sensitive matches '[A-Z]' and
      use dynamic method calling from a generated string, either 
      $y."ToLower"()
      $y."ToUpper"()
      to force the match
-join the loop output into a replacement string

Casos de prueba:

function f {
param($T,$F,$R)[regex]::Replace($T,'(?i)'+[regex]::escape($F),{param($m)-join(0..$R.Length|%{(($y=$R[$_]),("$y"."To$((('Low','Upp')[($z="$m"[$_])-cmatch($C='[A-Z]')]))er"()))[$z-match$C]})})
}

Import-Module Pester

$Cases = @(
    @{Text = "Text input"; Find = "text"; Replace = "test"; Result = "Test input" }
    @{Text = "tHiS Is a PiEcE oF tExT"; Find = "is"; Replace = "abcde"; Result = "tHaBcde Abcde a PiEcE oF tExT" }
    @{Text = "The birch canoe slid on the smooth planks"; Find = "o"; Replace = " OH MY "; Result = "The birch can OH MY e slid  OH MY n the sm OH MY  OH MY th planks" }
    @{Text = "The score was 10 to 5"; Find = "10"; Replace = "tEn"; Result = "The score was tEn to 5" }
    @{Text = "I wrote my code in Brain$#@!"; Find = "$#@!"; Replace = "Friend"; Result = "I wrote my code in BrainFriend" }
    @{Text = "This challenge was created by Andrew Piliser"; Find = "Andrew Piliser"; Replace = "Martin Ender"; Result = "This challenge was created by Martin Ender" }
    @{Text = "John does not know"; Find = "John Doe"; Replace = "Jane Doe" ; Result ="Jane does not know" }
    @{Text = "Glue the sheet to the dark blue background"; Find = "Glue the sheet to the dark-blue background"; Replace = "foo"; Result ="Glue the sheet to the dark blue background" }
    @{Text = "aaa" ; Find = "aa"; Replace = "b"; Result ="ba" }
    @{Text = "aaaa"; Find = "aa"; Replace = "a"; Result ="aa" }
    @{Text = "TeXT input"; Find = "text"; Replace = "test"; Result ="TeST input" }
)

Describe "Tests" {

    It "works on /<Text>/<Find>/<Replace>/ == '<Result>'" -TestCases $Cases {
        param($Text, $Find, $Replace, $Result)
        f $Text $Find $Replace | Should -BeExactly $Result
    }

}

1

TXR Lisp, 285 bytes

(defun f(s f r)(let*((w(copy s))(x(regex-compile ^(compound,(upcase-str f))))(m(reverse(tok-where(upcase-str s)x))))(each((n m))(set[w n]r) (for((i(from n)))((< i (min(to n)(len w))))((inc i))(cond((chr-isupper[s i])(upd[w i]chr-toupper))((chr-islower[s i])(upd[w i]chr-tolower)))))w))

Original con formato convencional:

(defun f (s f r)
  (let* ((w (copy s))
         (x (regex-compile ^(compound ,(upcase-str f))))
         (m (reverse (tok-where (upcase-str s) x))))
    (each ((n m))
      (set [w n] r)
      (for ((i (from n))) ((< i (min (to n) (len w)))) ((inc i))
        (cond ((chr-isupper [s i]) (upd [w i] chr-toupper))
              ((chr-islower [s i]) (upd [w i] chr-tolower)))))
    w))

1

JavaScript, 177 bytes

(T,F,R)=>T.replace(eval(`/${F.replace(/[-\/\\^$*+?.()|[\]{}]/g,'\\$&')}/gi`),F=>[...R].map((r,i)=>/[A-Z]/i.test(f=F[i]||'')?r[`to${f>'`'&&f<'{'?'Low':'Upp'}erCase`]():r).join``)

Menos golfizado:

(T,F,R) => T.replace(
    eval(`/${F.replace(/[-\/\\^$*+?.()|[\]{}]/g,'\\$&')}/gi`),
    F=>[...R].map((r,i) =>
        /[A-Z]/i.test(f = F[i] || '')
            ? r[`to${
                f > '`' && f < '{'
                    ? 'Low'
                    : 'Upp'
                }erCase`]()
            : r
    ).join``
)

47 bytes provienen de esta función de escape regex ya que el programa tiene que manejar símbolos. :(


1

Python 2 , 193 200 bytes

T,F,R=input()
w=str.lower
i=-len(T)
l=len(F)
T+=' '
while i:
 s=T[i:i+l]
 if w(s)==w(F):T=T[:i]+`[[y,[w(y),y.upper()][x<'a']][x.isalpha()]for x,y in zip(s,R)]`[2::5]+R[l:]+T[i+l:];i+=l-1
 i+=1
print T

Pruébalo en línea!


Esto (193 bytes, desde el enlace TIO) no podrá encontrar coincidencias al final de la cadena.
tehtmi

1

Python 3 , 183 bytes

import re
j="".join
f=lambda T,F,R:j((p,j((y,(y.lower(),y.upper())[x<'a'])[x.isalpha()]for(x,y)in zip(p,R))+R[len(F):])[i%2>0]for i,p in enumerate(re.split('('+re.escape(F)+')',T,0,2)))

Pruébalo en línea!

re.split + mantenga todos los elementos pares y reemplace todos los elementos impares por la transformación correcta de la cadena de reemplazo:

>>> re.split("(is)","tHiS Is a PiEcE oF tExT",0,2) # 2=re.IGNORE_CASE
['tH', 'iS', ' ', 'Is', ' a PiEcE oF tExT']

1

C (gcc) , 210 211 207 189 bytes

Tuve que agregar un byte para corregir un error con las mayúsculas para el caso de prueba "BrainFriend"

Wow, esto era tedioso ... Ahora, para jugar al golf, algunos bytes

char*c,*p;d,l;f(t,f,r){for(d=isalpha(*(p=f)),p=c=t;c=strcasestr(c,f);p=c+=l>0?l:0){for(l=strlen(f);p<c;)putchar(*p++);for(p=r;*p;p++,c+=l-->0)putchar(d*l<1?*p:*c&32?*p|32:*p&~32);}puts(p);}

Pruébalo en línea!


Probablemente me estoy perdiendo algo obvio, pero ¿por qué necesita el *(p=f)cuando establece p=c=tjusto después? Lo probé solo *fy no funcionó, por lo que no se sobrescribe de inmediato.
Andrew

f es por defecto un int, así que no podemos desreferenciarlo para obtener un char, pero p es un char *
cleblanc

Ah, eso tiene sentido. Entonces, ¿es una forma más corta de escribir *((char*)f)? ¡Frio!
Andrew

1

C # (compilador Mono C #) , 241 bytes

using System.Text.RegularExpressions;
class Program {
static void Main(string[] args) {
r("Text input","text","Test");
}
static void r(string v,string i,string u)
{
System.Console.WriteLine(Regex.Replace(v,i,u,RegexOptions.IgnoreCase)); 
}
}

Pruébalo en línea!


1
Bienvenido a PPCG! Puede eliminar un poco de espacio en blanco aquí, y en realidad necesita tomar las entradas como argumentos o entradas (está prohibido codificarlas) o puede simplemente incluir la función; ni siquiera necesitas la Action<string,string,string> r =parte
HyperNeutrino
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.