Caso corrispondente Trova Sostituisci


14

Prendi tre input, una stringa di testo T; una stringa di caratteri da sostituire F,; e una serie di caratteri per sostituirli con R,. Per ogni sottostringa Tcon caratteri uguali (senza distinzione tra maiuscole e minuscole) F, sostituirli con i caratteri in R. Tuttavia, mantieni lo stesso caso del testo originale.

Se ci sono più caratteri Rrispetto F, i caratteri extra dovrebbe essere lo stesso caso come sono in R. Se sono presenti numeri o simboli F, i caratteri corrispondenti Rdevono conservare il caso in cui si trovano R. Fnon apparirà necessariamente in T.

Puoi supporre che tutto il testo sia compreso nell'intervallo ASCII stampabile.

Esempi

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


Richiesta di un esempio con involucro strano:"TeXT input", "text", "test"
Ingegnere Toast,

@EngineerToast Aggiunto esempio
Andrew

Non so perché ho trovato "The birch canoe slid on the smooth planks", "o", " OH MY "così divertente, ma ho adorato quell'esempio.
Magic Octopus Urn

Risposte:


3

Retina , 116 byte

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

Provalo online! Spiegazione:

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

Questa ricerca Te ogni volta che c'è una corrispondenza senza distinzione tra maiuscole e minuscole contro il lookahead alla Fpartita viene racchiusa in una serie di nuove righe e Rviene anche inserito il lookahead .

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

Ogni lettera della copia di Rviene adattata nel caso corrisponda a quella della corrispondenza, a seguito della quale viene spostata fuori dall'area di lavoro in modo che la lettera successiva possa essere elaborata, fino a quando la copia Ro la corrispondenza si esauriscono.

¶¶¶¶.*|¶

Se la copia di Resaurisce le lettere, il resto della partita sarà preceduto da 4 nuove righe, quindi eliminalo. Altrimenti, tutto ciò che resta sarà lasciato delle copie di Rcui è necessario concatenarsi con le parti non corrispondenti dell'input per produrre il risultato.


3

APL (Dyalog) , 75 73 72 byte

Prompt per T, Re Fin questo ordine. Rdeve essere indicato nel formato di trasformazione Dyalog e Fdeve essere indicato nel formato PCRE.

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

Provalo online!

 richiedere T

 cedere che (separa 1 e T)

⍞⎕R(... )⍠1 pronta per Fe R partite EPosizionare con il risultato della seguente funzione:

⍞∘{…} derivare una funzione monadica legando l' Rargomento richiesto come argomento sinistro a:

  ≢⍺ contare il numero di lettere in R

  ⍺⍵.Match↑¨⍨ prendi tante lettere da ognuna di esse Re la corrispondenza
   è l'argomento sinistro, che abbiamo legato Rcome.
   è uno spazio dei nomi in cui Matchcontiene la stringa attualmente trovata.

   mescola quei due in una matrice a due file

  d← conservare come d

  (... )  applica la seguente funzione tacita a quella:

   819⌶ minuscolo (mnemonico: 819 sembra grande )

   l← memorizzare quella funzione come l

  d≠ Booleano dove ddifferisce (ovvero dà 0/1 per ogni lettera minuscola / maiuscola)

  (... ) applica la seguente funzione tacita a quella:

   ≠⌿ XOR verticale

   (... )∧ booleano AND con il seguente array:

    l⎕A in minuscolo A lphabet

    ⎕A,anteporre una  lettera maiuscola

    d∊ Booleano per ogni lettera in d se un membro di quella (cioè se una lettera)

    ⊢⌿ ultima riga, ad esempio per il carattere della partita, sia che si tratti di una lettera

   1∘⌷≠ XOR con la prima riga, ovvero se ogni carattere di Rè maiuscolo

  (... )l¨⍨ usalo per minuscole (se 0) o maiuscole (se 1) ogni lettera di:

   ⊣⌿ la prima fila, cioè R


* Conteggio byte per Dyalog Classic utilizzando ⎕OPT invece di .



2

Ritirato. La risposta di Dom la batte da una possibilità.

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

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

Provalo online!

fatto un taglio enorme dopo aver menzionato @Dom Hastings \Q

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

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}

Provalo online!


Passa subito tutti i casi di test;) 108: Provalo online!
Dom Hastings,

Dovresti pubblicarlo. Batte il mio di un bel po '.
Xcali,

Giusto! È stato divertente farlo. Mi piace la sfida!
Dom Hastings,

2

PowerShell , 190 byte

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

Provalo online!

Spiegazione:

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

Lo script di blocco di sostituzione fa:

$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

Casi test:

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 byte

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

Originale formattato in modo convenzionale:

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

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

Meno golf:

(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 byte provenivano da questa funzione di escape regex poiché il programma deve gestire i simboli. :(


1

Python 2 , 193 200 byte

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

Provalo online!


Questo (193 byte, dal collegamento TIO) non riuscirà a trovare le corrispondenze alla fine della stringa.
tehtmi,

1

Python 3 , 183 byte

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

Provalo online!

re.split + mantieni tutti gli elementi pari e sostituisci tutti gli elementi dispari con la corretta trasformazione della stringa di sostituzione:

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

Ho dovuto aggiungere un byte per correggere un bug con la maiuscola per la testcase "BrainFriend"

Caspita, questo era noioso ... Ora per golf via alcuni byte

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

Provalo online!


Probabilmente mi manca qualcosa di ovvio, ma perché hai bisogno di *(p=f)quando ti metti p=c=tsubito dopo? L'ho provato solo *fe non ha funzionato, quindi non viene sovrascritto immediatamente.
Andrew,

f è per impostazione predefinita un int quindi non possiamo dereferenziarlo per ottenere un carattere, ma p è un carattere *
cleblanc

Ah, ha senso. Quindi è un modo più breve di scrivere *((char*)f)? Freddo!
Andrew,

1

C # (compilatore Mono C #) , 241 byte

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

Provalo online!


1
Benvenuti in PPCG! Puoi rimuovere un bel po 'di spazio qui, e in realtà devi prendere gli input come argomenti o input (è vietato codificarli) o potresti semplicemente includere la funzione; non hai nemmeno bisogno della Action<string,string,string> r =parte
HyperNeutrino,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.