대소 문자 일치 찾기 바꾸기


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

@EngineerToast 추가 된 예
Andrew

내가 왜 "The birch canoe slid on the smooth planks", "o", " OH MY "그렇게 유머러스 한지 알지 못했지만 그 예를 좋아했습니다.
매직 문어 Urn

답변:


3

레티 나 116 바이트

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

온라인으로 사용해보십시오! 설명:

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

이것은 검색 T하고 일치하는 lookahead에 대해 대 / 소문자를 구분하지 않는 일치가있을 때마다 줄 F바꿈으로 묶여 있고 lookahead R도 삽입됩니다.

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

사본의 각 문자는 R일치하는 문자와 일치하도록 조정되며, 그 후에는 사본 R또는 일치하는 문자가 없어 질 때까지 다음 문자를 처리 할 수 ​​있도록 작업 영역 밖으로 이동합니다 .

¶¶¶¶.*|¶

의 사본 경우 R문자 중 실행이 다음 경기의 나머지 4 개행 문자로 시작되므로, 삭제합니다. 그렇지 않으면, 남은 것은 남은 사본 조각으로 R결과의 일치하지 않는 입력 부분과 연결되어 결과를 생성해야합니다.


3

APL (Dyalog) , 75 73 72 바이트

프롬프트에 대한 T, R그리고 F그 순서이다. Rb는 Dyalog 변환 형식 F으로 제공되어야하고 PCRE 형식으로 제공되어야합니다.

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

온라인으로 사용해보십시오!

 묻다 T

 수확량 (1과 T)

⍞⎕R(... )⍠1 에 대한 프롬프트 FR 다음 함수의 결과 eplace 경기 :

⍞∘{…} 프롬프트 R를 왼쪽 인수로 묶어 모나 딕 함수를 도출합니다 .

  ≢⍺ 글자 수를 세다 R

  ⍺⍵.Match↑¨⍨ 각각에서 그 많은 글자를 가져 와서 R일치하는
   것은 우리가 묶은 왼쪽 논쟁 R입니다. 현재 찾은 문자열
   Match포함 된 네임 스페이스입니다 .

   이 두 행을 2 행 행렬로 섞습니다

  d← 로 저장 d

  ()  다음의 암묵적 기능을 적용하십시오.

   819⌶ 소문자 (니모닉 : 819Big 처럼 보입니다 )

   l← 해당 기능을 다음과 같이 저장하십시오 l

  d≠d다른  부울 (예 : 각 소문자 / 대문자에 0/1을 제공함)

  () 다음의 암묵적 기능을 적용하십시오.

   ≠⌿ 수직 XOR

   ()∧ 다음 배열의 부울 AND

    l⎕A 소문자 lphabet

    ⎕A,접두사  대문자 A lphabet

    d∊ d의 각 문자에 대한 부울 해당 멤버인지 여부 (즉, 문자인지 여부)

    ⊢⌿ 마지막 행, 즉 문자의 일치 여부를 나타내는 문자

   1∘⌷≠ 첫 번째 행의 XOR, 즉의 각 문자 R가 대문자 인지 여부

  (… 다음을 )l¨⍨ 사용하여 각 문자를 소문자 (0 인 경우) 또는 대문자 (1 인 경우)로 사용하십시오.

   ⊣⌿ 첫 번째 행, 즉 R


* ⎕OPT 대신을 사용 하는 Dyalog Classic의 바이트 수 .



2

빼는. Dom의 대답은 멀리서 이겼습니다.

# 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 : 온라인으로 사용해보십시오!
Dom Hastings

게시해야합니다. 그것은 꽤 많이 내 것을 친다.
Xcali

그럴 수 있지! 재미있었습니다. 나는 도전을 즐긴다!
Dom Hastings

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 리스프, 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

자바 스크립트, 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

파이썬 2 , 193 200 바이트

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

온라인으로 사용해보십시오!


이 문자열 (TIO 링크에서 193 바이트)은 문자열 끝에서 일치 항목을 찾지 못합니다.
tehtmi

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"테스트 케이스의 대문자로 버그를 수정하기 위해 1 바이트를 추가해야했습니다.

와우이 지루 했어 ... 이제 몇 바이트 떨어져 골프

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는 betault 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.