Dopasowywanie wielkości liter Znajdź Zamień

14

Weź trzy dane wejściowe, ciąg tekstu T; ciąg znaków do zastąpienia F; i ciąg znaków, aby zastąpić je, R. Dla każdego podłańcucha o Ttakich samych (bez rozróżniania wielkości liter) znaków F, zamień je na znaki w R. Zachowaj jednak taką samą wielkość liter jak oryginalny tekst.

Jeśli istnieje więcej znaków Rniż F, dodatkowe znaki powinny mieć ten sam przypadek, ponieważ są one w R. Jeśli są cyfry lub symbole F, to odpowiednie znaki Rpowinny zachować wielkość liter R. Fniekoniecznie pojawi się w T.

Możesz założyć, że cały tekst będzie w drukowanym zakresie ASCII.

Przykłady

"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"

Link do piaskownicy

Andrzej
źródło
Prośba o przykład z dziwną obudową:"TeXT input", "text", "test"
Toast inżynierski
@EngineerToast Dodano przykład
Andrew
Nie jestem pewien, dlaczego uważałem "The birch canoe slid on the smooth planks", "o", " OH MY "to za zabawne, ale podobał mi się ten przykład.
Magic Octopus Urn

Odpowiedzi:

3

Siatkówka , 116 bajtów

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

Wypróbuj online! Wyjaśnienie:

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

Wyszukuje Ti za każdym razem, gdy rozróżniana jest wielkość liter w stosunku do lookahead, Fdopasowanie jest otaczane przez kilka nowych linii, a lookahead Rjest również wstawiany.

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

Każda litera kopii Rjest dopasowywana, aby pasowała do litery dopasowania, po czym jest przenoszona poza obszar roboczy, aby można było przetworzyć kolejną literę, dopóki kopia Rlub dopasowanie nie zabraknie liter.

¶¶¶¶.*|¶

Jeśli w kopii Rzabraknie liter, pozostała część dopasowania będzie poprzedzona 4 znakami nowej linii, więc usuń ją. W przeciwnym razie wszystko, co pozostanie, pozostanie fragmentami kopii, Rktóre należy połączyć z niepasującymi częściami danych wejściowych, aby uzyskać wynik.

Neil
źródło
3

APL (Dyalog) , 75 73 72 bajtów

Zachęty dla T, Ri Fw tej kolejności. Rmusi być podany w formacie transformacji Dyalog i Fmusi być podany w formacie PCRE.

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

Wypróbuj online!

 monit o T

 wydajność, która (oddziela 1 i T)

⍞⎕R(... )⍠1 zachęty dla Fi R mecze EUmieãæ o wyniku następujących funkcji:

⍞∘{…} wyprowadzić funkcję monadyczną, wiążąc podpowiedzi Rjako lewy argument do:

  ≢⍺ policz liczbę liter w R

  ⍺⍵.Match↑¨⍨ weź tyle liter z każdego z nich, Ra dopasowanie
   jest lewym argumentem, który powiązaliśmy Rjako.
   to przestrzeń nazw, w której Matchznajduje się aktualnie znaleziony ciąg.

   zmieszaj te dwa w dwurzędową macierz

  d← przechowywać jako d

  ()  Zastosuj do tego następującą milczącą funkcję:

   819⌶ małe litery (mnemoniczny: 819 wygląda jak duży )

   l← zapisz tę funkcję jako l

  d≠ Boolean, gdzie się dróżni (tzn. Daje 0/1 dla każdej małej / wielkiej litery)

  () Zastosuj do tego następującą milczącą funkcję:

   ≠⌿ pionowy XOR

   ()∧ Boolean AND z następującą tablicą:

    l⎕A małe litery A alfabet

    ⎕A, poprzedzać wielką literę A alfabet

    d∊ Wartość logiczna dla każdej litery in d, czy jej członek (tj. Czy litera)

    ⊢⌿ ostatni wiersz, tj. znak dopasowania, czy jest to litera

   1∘⌷≠ XOR z pierwszym wierszem, tzn. Czy każdy znak Rjest wielką literą

  ()l¨⍨ Używaj tego do małych (jeśli 0) lub wielkich (jeśli 1) każdej litery:

   ⊣⌿ pierwszy rząd, tj R


* Liczba bajtów dla Dyalog Classic przy użyciu ⎕OPT zamiast .

Adám
źródło
2

Perl 5 , 108 bajtów

Kod 107 bajtów + 1 dla -p.

chomp(($s,$r)=<>);s|\Q$s|$&=~s!.!$_=substr$r,"@-",1;$&=~/[a-z]/i?$&eq uc$&?uc:lc:$_!egr.substr$r,"@-"+1|gie

Wypróbuj online!

Dom Hastings
źródło
2

Wycofane. Odpowiedź Dom pokonuje ją z dystansu.

# Perl 5 , 136 + 1 (-p) = 137 bajtów

$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}

Wypróbuj online!

dokonał ogromnego cięcia po wspomnianej @Dom Hastings \Q

# Perl 5 , 176 + 1 (-p) = 177 bajtów

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}

Wypróbuj online!

Xcali
źródło
Przechodzi teraz wszystkie przypadki testowe;) 108: Wypróbuj online!
Dom Hastings
Powinieneś to opublikować. Trochę mnie bije.
Xcali
Słusznie! Zabawnie było to robić. Lubię wyzwanie!
Dom Hastings
2

PowerShell , 190 bajtów

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]})})

Wypróbuj online!

Wyjaśnienie:

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

Zamienny skrypt blokujący:

$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

Przypadki testowe:

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
    }

}
TessellatingHeckler
źródło
1

TXR Lisp, 285 bajtów

(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))

Oryginał sformatowany tradycyjnie:

(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))
Kaz
źródło
1

JavaScript, 177 bajtów

(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``)

Mniej golfa:

(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 bajtów pochodzi z tej funkcji zmiany wyrażenia regularnego, ponieważ program musi obsługiwać symbole. :(

darrylyeo
źródło
1

Python 2 , 193 200 bajtów

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

Wypróbuj online!

Pręt
źródło
To (193 bajtów, z łącza TIO) nie znajdzie dopasowań na końcu ciągu.
tehtmi
1

Python 3 , 183 bajtów

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)))

Wypróbuj online!

re.split + zachowaj wszystkie parzyste elementy i zastąp wszystkie nieparzyste elementy poprawną transformacją łańcucha zastępującego:

>>> re.split("(is)","tHiS Is a PiEcE oF tExT",0,2) # 2=re.IGNORE_CASE
['tH', 'iS', ' ', 'Is', ' a PiEcE oF tExT']
Jferard
źródło
1

C (gcc) , 210 211 207 189 bajtów

Musiałem dodać jeden bajt, aby naprawić błąd z wielkimi literami dla przypadku testowego „BrainFriend”

Wow, to było nudne ... Teraz pograć w golfa trochę bajtów

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);}

Wypróbuj online!

cleblanc
źródło
Prawdopodobnie brakuje mi czegoś oczywistego, ale dlaczego potrzebujesz, *(p=f)kiedy ustawiasz p=c=tzaraz potem? Próbowałem z tym po prostu *fi nie działało, więc nie jest natychmiast zastępowane.
Andrew
f to befault an int, więc nie możemy wyłapać go, aby uzyskać znak, ale p to znak *
cleblanc
Ach, to ma sens. Więc to krótszy sposób pisania *((char*)f)? Chłodny!
Andrew
1

C # (kompilator Mono C #) , 241 bajtów

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)); 
}
}

Wypróbuj online!

rywal
źródło
1
Witamy w PPCG! Możesz usunąć sporo białych znaków tutaj i faktycznie musisz wziąć dane wejściowe jako argumenty lub dane wejściowe (kodowanie ich jest zabronione) lub możesz po prostu włączyć funkcję; nawet nie potrzebujesz tej Action<string,string,string> r =części
HyperNeutrino,