Recherche de remplacement de correspondance de cas


14

Prenez trois entrées, une chaîne de texte T,; une chaîne de caractères à remplacer F,; et une chaîne de caractères pour les remplacer par, R. Pour chaque sous-chaîne de Tavec les mêmes caractères (insensibles à la casse) que F, remplacez-les par les caractères dans R. Cependant, conservez la même casse que le texte d'origine.

S'il y a plus de caractères Rque F, les caractères supplémentaires doivent être dans le même cas que dans R. S'il y a des chiffres ou des symboles F, les caractères correspondants Rdoivent conserver la casse qu'ils contiennent R. Fn'apparaîtra pas nécessairement dans T.

Vous pouvez supposer que tout le texte sera dans la plage ASCII imprimable.

Exemples

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

Lien Sandbox


Demander un exemple avec un boîtier étrange:"TeXT input", "text", "test"
Engineer Toast

@EngineerToast Exemple ajouté
Andrew

Je ne sais pas pourquoi j'ai trouvé "The birch canoe slid on the smooth planks", "o", " OH MY "si drôle, mais j'ai adoré cet exemple.
Urne de poulpe magique

Réponses:


3

Rétine , 116 octets

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

Essayez-le en ligne! Explication:

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

Cette recherche Tet chaque fois qu'il existe une correspondance insensible à la casse par rapport à l'anticipation de Fla correspondance est entourée d'un tas de nouvelles lignes et l'anticipation Rest également insérée.

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

Chaque lettre de la copie de Rest ajustée au cas où elle correspond à celle de la correspondance, après quoi elle est déplacée hors de la zone de travail afin que la lettre suivante puisse être traitée, jusqu'à ce que la copie Rou la correspondance soit épuisée.

¶¶¶¶.*|¶

Si la copie de Rmanque de lettres, le reste de la correspondance sera précédé de 4 nouvelles lignes, supprimez-le donc. Sinon, tout ce qui restera sera des morceaux de copies restants Rqui doivent être concaténés avec les parties non correspondantes de l'entrée pour produire le résultat.


3

APL (Dyalog) , 75 73 72 octets

Invite pour T, Ret Fdans cet ordre. Rdoit être donné au format de transformation Dyalog et Fdoit être donné au format PCRE.

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

Essayez-le en ligne!

 demander T

 donner que (sépare 1 et T)

⍞⎕R()⍠1  invite pour Fet R matches EPlacez avec le résultat de la fonction suivante:

⍞∘{…} dériver une fonction monadique en liant l' Rargument invité comme gauche à:

  ≢⍺ compter le nombre de lettres R

  ⍺⍵.Match↑¨⍨ prenez autant de lettres de chacun Ret la correspondance
   est l'argument de gauche, que nous avons lié Rcomme.
   est un espace de noms dans lequel Matchcontient la chaîne actuellement trouvée.

   mélanger ces deux dans une matrice à deux rangées

  d← stocker sous d

  ()   Appliquer à cela la fonction tacite suivante:

   819⌶ minuscule (mnémonique: 819 ressemble à gros )

   l← stocker cette fonction comme l

  d≠ Booléen où d diffère (ie donne 0/1 pour chaque lettre minuscule / majuscule)

  ()  Appliquer à cela la fonction tacite suivante:

   ≠⌿ XOR vertical

   ()∧  Booléen ET avec le tableau suivant:

    l⎕AA  minuscule alphabet en

    ⎕A, ajouter un A majusculeajouter alphabet

    d∊ Booléen pour chaque lettre en d si un membre de celle-ci (c'est-à-dire si une lettre)

    ⊢⌿ dernière ligne, c.-à-d. pour le caractère du match, qu'il s'agisse d'une lettre

   1∘⌷≠ XOR avec la première ligne, c'est-à-dire si chaque caractère de R est en majuscule

  ()l¨⍨  Utilisez-le pour minuscule (si 0) ou majuscule (si 1) chaque lettre de:

   ⊣⌿ la première rangée, c.-à-d. R


* Nombre d'octets pour Dyalog Classic utilisant ⎕OPT au lieu de .



2

Retiré. La réponse de Dom la bat de loin.

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

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

Essayez-le en ligne!

fait une énorme coupure après @Dom Hastings mentionné \Q

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

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}

Essayez-le en ligne!


Réussit tous les cas de test maintenant;) 108: Essayez-le en ligne!
Dom Hastings

Vous devez le poster. Il bat un peu le mien.
Xcali

C'est suffisant! C'était amusant de le faire. J'aime le défi!
Dom Hastings

2

PowerShell , 190 octets

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

Essayez-le en ligne!

Explication:

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

Le bloc de script de remplacement fait:

$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

Cas de 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 octets

(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 au format conventionnel:

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

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

Moins 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 octets provenaient de cette fonction d'échappement regex puisque le programme doit gérer les symboles. :(


1

Python 2 , 193 200 octets

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

Essayez-le en ligne!


Cela (193 octets, à partir du lien TIO) ne trouvera pas de correspondances à la fin de la chaîne.
tehtmi

1

Python 3 , 183 octets

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

Essayez-le en ligne!

re.split + conserver tous les éléments pairs et remplacer tous les éléments impairs par la transformation correcte de la chaîne de remplacement:

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

J'ai dû ajouter un octet pour corriger un bogue avec la mise en majuscule du testcase "BrainFriend"

Wow était-ce fastidieux ... Maintenant pour jouer au golf quelques octets

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

Essayez-le en ligne!


Il me manque probablement quelque chose d'évident, mais pourquoi avez-vous besoin du *(p=f)quand vous vous mettez p=c=tjuste après? Je l'ai essayé avec juste *fet cela n'a pas fonctionné, donc il n'est pas immédiatement écrasé.
Andrew

f est par défaut un int donc nous ne pouvons pas le déréférencer pour obtenir un caractère, mais p est un caractère *
cleblanc

Ah, ça a du sens. C'est donc une façon d'écrire plus courte *((char*)f)? Cool!
Andrew

1

C # (compilateur mono C #) , 241 octets

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

Essayez-le en ligne!


1
Bienvenue chez PPCG! Vous pouvez supprimer un grand nombre d'espaces ici, et en fait vous devez soit prendre les entrées comme arguments ou entrées (leur codage est interdit), soit vous pouvez simplement inclure la fonction; vous n'avez même pas besoin de la Action<string,string,string> r =pièce
HyperNeutrino
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.