การจับคู่กรณีค้นหาแทนที่


14

รับสามอินพุตสตริงข้อความT; สตริงอักขระที่จะแทนที่F; และสตริงอักขระที่จะแทนที่ด้วย, R. สำหรับแต่ละย่อยของTแบบเดียวกับที่ (กรณีตาย) เป็นตัวละครF, Rแทนที่พวกเขากับตัวละครใน อย่างไรก็ตามให้เป็นกรณีเดียวกันกับข้อความต้นฉบับ

หากมีตัวละครอื่น ๆ ในRกว่าตัวละครพิเศษควรจะเป็นกรณีเดียวกับที่พวกเขาอยู่ในF Rหากมีตัวเลขหรือสัญลักษณ์ในFแล้วตัวละครที่เกี่ยวข้องในควรเก็บไว้ในกรณีที่พวกเขาได้ในR จะไม่จำเป็นต้องปรากฏในRFT

คุณสามารถสมมติว่าข้อความทั้งหมดจะอยู่ในช่วง 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"

ลิงก์ Sandbox


ขอตัวอย่างพร้อมปลอกแปลก ๆ :"TeXT input", "text", "test"
วิศวกร Toast

@EngineerToast เพิ่มตัวอย่าง
Andrew

ไม่แน่ใจว่าทำไมฉันถึงพบ"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และเมื่อใดก็ตามที่มีการแข่งขันแบบตรงตามตัวพิมพ์เล็กและใหญ่กับ 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ตามลำดับนั้น Rต้อง b ที่กำหนดในรูปแบบการแปลง Dyalog และFต้องกำหนดในรูปแบบ PCRE

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

ลองออนไลน์!

 แจ้งให้ T

 ให้ผลที่ (แยก 1 และT)

⍞⎕R(... )⍠1 แจ้งให้FและR eplace จับคู่กับผลลัพธ์ของฟังก์ชันต่อไปนี้:

⍞∘{…} ได้รับฟังก์ชัน monadic โดยผูกRอาร์กิวเมนต์prompt-for เป็น:

  ≢⍺ นับจำนวนตัวอักษร R

  ⍺⍵.Match↑¨⍨ ใช้เวลาที่หลายฉบับจากแต่ละRและการแข่งขัน
   เป็นอาร์กิวเมนต์ซ้ายซึ่งเราผูกRเป็น
   เป็นเนมสเปซที่Matchมีสตริงที่พบในปัจจุบัน

   ผสมสองเหล่านั้นเข้ากับเมทริกซ์สองแถว

  d← เก็บเป็น d

  (... )  ใช้ฟังก์ชัน tacit ต่อไปนี้กับสิ่งนั้น:

   819⌶ ตัวพิมพ์เล็ก (ตัวช่วยจำ: 819ดูเหมือนใหญ่ )

   l← เก็บฟังก์ชั่นที่เป็น l

  d≠ บูลีนที่dแตกต่าง (เช่นให้ 0/1 สำหรับตัวอักษรตัวพิมพ์เล็ก / ตัวพิมพ์ใหญ่แต่ละตัว)

  (... ) ใช้ฟังก์ชัน tacit ต่อไปนี้กับสิ่งนั้น:

   ≠⌿ XOR แนวตั้ง

   ()∧ บูลีนและด้วยอาเรย์ต่อไปนี้:

    l⎕A lowercased lphabet

    ⎕A, เติมตัวพิมพ์ใหญ่A lphabet

    d∊ บูลีนสำหรับตัวอักษรแต่ละตัวใน d ว่าเป็นสมาชิกของที่ (เช่นไม่ว่าจะเป็นตัวอักษร)

    ⊢⌿ แถวสุดท้ายคืออักขระของการแข่งขันไม่ว่าจะเป็นตัวอักษร

   1∘⌷≠ แฮคเกอร์ที่มีแถวแรกคืออักขระแต่ละตัวของRตัวพิมพ์ใหญ่หรือไม่

  (... )l¨⍨ ใช้ตัวพิมพ์เล็ก (ถ้า 0) หรือตัวพิมพ์ใหญ่ (ถ้า 1) ตัวอักษรแต่ละตัวของ:

   ⊣⌿ แถวแรกคือ R


* นับไบต์สำหรับ Dyalog คลาสสิกใช้แทน⎕OPT



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 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 bytes มาจากฟังก์ชั่นหลบหนี regex นี้เนื่องจากโปรแกรมมีการจัดการสัญลักษณ์ :(


1

Python 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

ลองออนไลน์!


นี่ (193 ไบต์จากลิงก์ TIO) จะไม่พบการแข่งขันที่ส่วนท้ายของสตริง
tehtmi

1

Python 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 ไบต์

ต้องเพิ่มหนึ่งไบต์เพื่อแก้ไขข้อผิดพลาดด้วยตัวพิมพ์ใหญ่สำหรับ testcase "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 ถูก befault int ดังนั้นเราจึงไม่สามารถปฏิเสธได้เพื่อรับถ่าน แต่ p เป็นถ่าน *
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.