Шукати відповідність Знайти замінити


14

Візьміть три входи, рядок тексту T; рядок символів для заміни F; і рядок символів , щоб замінити їх, R. Для кожної підрядки Tз тими самими (нечутливими до регістру) символами F, замініть їх символами в R. Однак збережіть той самий випадок, що і оригінальний текст.

Якщо є більше символів , Rніж F, додаткові символи повинні бути той же випадок , коли вони знаходяться в R. Якщо в ньому є цифри або символи F, то відповідні символи Rповинні зберігати випадок, у якому вони є R. Fне обов'язково відображатиметься в T.

Можна припустити, що весь текст буде знаходитись у діапазоні ASCII для друку.

Приклади

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

Посилання в пісочниці


Запит прикладу зі дивним корпусом:"TeXT input", "text", "test"
Інженер Тост

@EngineerToast Доданий приклад
Андрій

Не впевнений, чому я виявився "The birch canoe slid on the smooth planks", "o", " OH MY "таким жартівливим, але я любив цей приклад.
Magic Octopus Urn

Відповіді:


3

Сітківка , 116 байт

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

Спробуйте в Інтернеті!Пояснення:

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

Цей пошук шукає, Tі коли є невідчутне до регістру відповідність до пошуку F, оточується купою нових рядків іR .

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

Кожен лист копії Rпристосовується на випадок відповідності тому, що відповідає матчу, після чого він переміщується з робочої зони, щоб наступний лист міг бути оброблений, поки не буде виконана копіяR або збігу літер не закінчиться.

¶¶¶¶.*|¶

Якщо в копії не Rвистачає букв, то решті збігу передують 4 нові рядки, тому видаліть її. В іншому випадку все, що залишилося, залишиться частин копій, Rякі потрібно з'єднати з невідповідними частинами вводу для отримання результату.


3

APL (Діалог) , 75 73 72 байт

Підказки для T, Rі Fв такому порядку. Rповинен Fбути заданий у форматі перетворення Dyalog і повинен бути наданий у форматі PCRE.

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

Спробуйте в Інтернеті!

 підказка для T

 вихід, що (відокремлює 1 і T )

⍞⎕R(... )⍠1 Запитувати Fі R eplace матчі з результатом наступної функції:

⍞∘{…} вивести монадійну функцію, прив’язавши підказку до Rяк лівий аргумент:

  ≢⍺ підрахувати кількість букв у R

  ⍺⍵.Match↑¨⍨ візьміть, що багато літер від кожного, Rі збіг
   - це лівий аргумент, який ми зв'язали Rяк.
   являє собою простір імен, в якому Matchміститься знайдений нині рядок.

   змішайте ці дві у дворядну матрицю

  d← зберігати як d

  ()   Застосувати до цього таку негласну функцію:

   819⌶ нижній регістр (мнемонічний: 819 виглядає як великий )

   l← зберігати цю функцію як l

  d≠ Булева де d відрізняється (тобто дає 0/1 для кожної малої та малої літери)

  () Застосувати до цього таку негласну функцію:

   ≠⌿ вертикальний XOR

   ()∧ Булева І зі наступним масивом:

    l⎕A нижній регістр A lphabet

    ⎕A,передній  верхній регістр A lphabet

    d∊ Булева для кожної літери в d, чи є членом цього (тобто чи буквою)

    ⊢⌿ останній рядок, тобто для символу збігу, чи це літера

   1∘⌷≠ XOR з першим рядком, тобто чи є кожний символ Rверхнього регістру

  ()l¨⍨  Використовуйте це для малих літер (якщо 0) або великих літер (якщо 1) кожної літери:

   ⊣⌿ перший ряд, тобто R


* Кількість байтів для Dyalog Classic використовує ⎕OPT замість .



2

Вилучено. Відповідь Дома б'є це дальнім пострілом.

# Perl 5 , 136 + 1 (-p) = 137 байт

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

Спробуйте в Інтернеті!

зробив величезний розріз після згаданого @Dom Hastings \Q

# Perl 5 , 176 + 1 (-p) = 177 байт

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}

Спробуйте в Інтернеті!


Проходить усі тестові випадки зараз;) 108: Спробуйте в Інтернеті!
Дом Гастінгс

Ви повинні опублікувати його. Це б’є моє зовсім небагато.
Xcali

Справедливо! Було весело, роблячи це. Мені подобається виклик!
Дом Гастінгс

2

PowerShell , 190 байт

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

Спробуйте в Інтернеті!

Пояснення:

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

Блок скриптів заміни виконує:

$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

Тестові приклади:

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 байт

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

Умовно відформатований оригінал:

(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 байт

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

Менше гольфу:

(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 байт надійшло від цієї функції втечі від регулярних виразів, оскільки програма повинна обробляти символи. :(



1

Пітон 3 , 183 байти

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

Спробуйте в Інтернеті!

re.split + збережіть усі парні елементи та замініть усі непарні елементи правильним перетворенням рядка заміни:

>>> 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 байт

Довелося додати один байт, щоб виправити помилку з великої літери для тесту "BrainFriend"

Нічого собі це не нудно ... Тепер відібрати кілька байтів

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

Спробуйте в Інтернеті!


Я, мабуть, пропускаю щось очевидне, але навіщо тобі потрібен той *(p=f)момент, коли ти встановлюєш p=c=tлише згодом? Я спробував це просто, *fі це не вийшло, так що це не відразу перезаписується.
Андрій

f за замовчуванням є int, тому ми не можемо знеструмити його, щоб отримати знак char, але p - це char *
cleblanc

Ах, це має сенс. Так це коротший спосіб написання *((char*)f)? Класно!
Андрій

1

C # (компілятор Mono C #) , 241 байт

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

Спробуйте в Інтернеті!


1
Ласкаво просимо до PPCG! Ви можете видалити тут трохи пробілів, і насправді вам потрібно взяти вхід як аргументи або введення (кодування їх заборонено), або ви могли фактично просто включити функцію; вам навіть не потрібна Action<string,string,string> r =частина
HyperNeutrino
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.