Duplikate aus einem String entfernen

17

Inspiriert von dieser bescheidenen StackOverflow-Frage .

Die Idee ist einfach; Entfernen Sie bei einem String und einem Array von Strings alle Instanzen von Wörtern im Array (Groß- / Kleinschreibung wird ignoriert) aus dem Eingabe-String (außer dem ersten) sowie alle zusätzlichen Whitespaces, die möglicherweise verbleiben. Die Wörter müssen mit ganzen Wörtern in der Eingabezeichenfolge und nicht mit Wortteilen übereinstimmen.

zB "A cat called matt sat on a mat and wore a hat A cat called matt sat on a mat and wore a hat", ["cat", "mat"]soll ausgeben"A cat called matt sat on a mat and wore a hat A called matt sat on a and wore a hat"

Eingang

  • Die Eingabe kann entweder als Zeichenfolge oder als Array von Zeichenfolgen oder als Array von Zeichenfolgen erfolgen, wobei die Eingabezeichenfolge das erste Element ist. Diese Parameter können in beliebiger Reihenfolge angegeben werden.
  • Die Eingabezeichenfolge darf nicht als Liste von durch Leerzeichen getrennten Zeichenfolgen verwendet werden.
  • Die Eingabezeichenfolge enthält keine führenden, nachfolgenden oder aufeinanderfolgenden Leerzeichen.
  • Alle Eingaben enthalten nur die Zeichen [A-Za-z0-9] mit Ausnahme der Eingabezeichenfolge, die auch Leerzeichen enthält.
  • Das Eingabearray kann leer sein oder Wörter enthalten, die nicht in der Eingabezeichenfolge enthalten sind.

Ausgabe

  • Die Ausgabe kann entweder der Rückgabewert einer Funktion sein oder auf STDOUT gedruckt werden
  • Die Ausgabe muss im selben Fall wie die ursprüngliche Zeichenfolge erfolgen

Testfälle

the blue frog lived in a blue house, [blue] -> the blue frog lived in a house
he liked to read but was filled with dread wherever he would tread while he read, [read] -> he liked to read but was filled with dread wherever he would tread while he
this sentence has no matches, [ten, cheese] -> this sentence has no matches
this one will also stay intact, [] -> this one will also stay intact
All the faith he had had had had no effect on the outcome of his life, [had] -> All the faith he had no effect on the outcome of his life
5 times 5 is 25, [5, 6] -> 5 times is 25
Case for different case, [case] -> Case for different
the letters in the array are in a different case, [In] -> the letters in the array are a different case
This is a test Will this be correct Both will be removed, [this,will] -> This is a test Will be correct Both be removed

Da dies Codegolf ist, gewinnt die niedrigste Byteanzahl!

Luke Stevens
quelle

Antworten:

9

R 84 Bytes

function(s,w,S=el(strsplit(s," ")),t=tolower)cat(S[!duplicated(x<-t(S))|!x%in%t(w)])

Probieren Sie es online!

Weniger als 100 Bytes bei einer Challenge, die nicht auch ?

Erläuterung:

Nachdem wir die Zeichenkette in Wörter zerlegt haben, müssen wir diejenigen ausschließen, die es sind

  1. Duplikate und
  2. im w

oder alternativ, drehen Sie das auf den Kopf, halten Sie die, die sind

  1. das erste Vorkommen eines Wortes ODER
  2. nicht in w.

duplicatedGibt logische Indizes derjenigen zurück, die nicht das erste Vorkommen sind, also !duplicated()Indizes derjenigen, die das erste Vorkommen sind, und x%in%wlogische Indizes xderjenigen, die sich in befinden w. Ordentlich.

Giuseppe
quelle
6

Java 8, 117 110 Bytes

a->s->{for(String x:a)for(x="(?i)(.*"+x+".* )"+x+"( |$)(.*)";s.matches(x);s=s.replaceAll(x,"$1$3"));return s;}

Erläuterung:

Probieren Sie es online aus.

a->s->{                // Method with String-array and String parameters and String return
  for(String x:a)      //  Loop over the input-array
    for(x="(?i)(.*"+x+".* )"+x+"( |$)(.*)";
                       //   Regex to match
        s.matches(x);  //   Inner loop as long as the input matches this regex
      s=s.replaceAll(x,"$1$3")); 
                       //    Replace the regex-match with the 1st and 3rd capture groups
  return s;}           //  Return the modified input-String

Zusätzliche Erklärung für den regulären Ausdruck:

(?i)(.*"+x+".* )"+x+"( |$)(.*)   // Main regex to match:
(?i)                             //  Enable case insensitivity
    (                            //  Open capture group 1
     .*                          //   Zero or more characters
       "+x+"                     //   The input-String
            .*                   //   Zero or more characters, followed by a space
               )                 //  End of capture group 1
                "+x+"            //  The input-String again
                     (           //  Open capture group 2
                       |$        //   Either a space or the end of the String
                         )       //  End of capture group 2
                          (      //  Open capture group 3
                           .*    //   Zero or more characters
                             )   //  End of capture group 3

$1$3                             // Replace the entire match with:
$1                               //  The match of capture group 1
  $3                             //  concatted with the match of capture group 3
Kevin Cruijssen
quelle
4

MATL , 19 18 Bytes

"Ybtk@kmFyfX<(~)Zc

Eingaben sind: ein Zellenarray von Zeichenfolgen, dann eine Zeichenfolge.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Wie es funktioniert

"        % Take 1st input (implicit): cell array of strings. For each
  Yb     %   Take 2nd input (implicit) in the first iteration: string; or
         %   use the string from previous iteration. Split on spaces. Gives
         %   a cell array of strings
  tk     %   Duplicate. Make lowercase
  @k     %   Push current string from the array taken as 1st input. Make
         %   lowercase
  m      %   Membership: gives true-false array containing true for strings
         %   in the first input argument that equal the string in the second
         %   input argument
  F      %   Push false
  y      %   Duplicate from below: pushes the true-false array again
  f      %   Find: integer indices of true entries (may be empty)
  X<     %   Minimum (may be empty)
  (      %   Assignment indexing: write false in the true-false array at that
         %   position. So this replaces the first true (if any) by false
  ~      %   Logical negate: false becomes true, true becomes false
  )      %   Reference indexing: in the array of (sub)strings that was
         %   obtained from the second input, keep only those indicated by the
         %   (negated) true-false array
  Zc     %   Join strings in the resulting array, with a space between them
         % End (implicit). Display (implicit)
Luis Mendo
quelle
3

Perl 5 , 49 Bytes

@B=<>;$_=join$",grep!(/^$_$/xi~~@B&&$v{+lc}++),@F

Probieren Sie es online!

9 (!!) Bytes dank @TonHospel gespeichert !

Dom Hastings
quelle
1
Dies scheint für This is a test Will this be correct Both will be removed+ zu scheitern this will. Die zweiten beiden Wörter werden korrekt entfernt, aber aus irgendeinem Grund wird auch das benach dem zweiten Wort entfernt will.
Kevin Cruijssen
1
@ KevinCruijssen Hmmm, ich kann sehen, warum das gerade passiert. Ich werde versuchen, mir morgen das Mittagessen anzuschauen, aber ich habe es vorerst auf einen Preis von +4 festgelegt. Danke für die Information!
Dom Hastings
Für 49:@B=<>;$_=join$",grep!(/^$_$/xi~~@B&&$v{+lc}++),@F
Ton Hospel
@TonHospel Ahh, verbrachte eine Weile damit, lcohne Eltern angerufen zu werden. Genial! Die Verwendung eines regulären Ausdrucks für das Array ist viel besser. Vielen Dank! Ich bemühe mich, mich an all deine Tipps zu erinnern!
Dom Hastings
2

Pyth, 27 Bytes

jdeMf!}r0eT@mr0dQmr0dPT._cz

Probieren Sie es online aus

Erläuterung

jdeMf!}r0eT@mr0dQmr0dPT._cz
                          z  Take the string input.
                       ._c   Get all the prefixes...
    f    eT@                 ... which end with something...
     !}         Q    PT      ... which is not in the input and the prefix...
       r0   mr0d mr0d        ... case insensitive.
jdeM                         Join the ends of each valid prefix.

Ich bin sicher, dass die 10 Bytes für die Prüfung auf Groß- und Kleinschreibung reduziert werden können, aber ich verstehe nicht, wie.


quelle
2

Stax , 21 Bytes CP437

åìøΓ²¬$M¥øHΘQä~╥ôtΔ♫╟

25 Bytes beim Auspacken,

vjcm[]Ii<;e{vm_]IU>*Ciyj@

Das Ergebnis ist ein Array. Die bequeme Ausgabe für Stax ist ein Element pro Zeile.

Online ausführen und debuggen!

Erläuterung

vj                           Convert 1st input to lowercase and split at spaces,
  c                          Duplicate at the main stack
   m                         Map array with the rest of the program 
                                 Implicitly output
    []I                      Get the first index of the current array element in the array
       i<                    Test 1: The first index is smaller than the iteration index
                                 i.e. not the first appearance
         ;                   2nd input
          {vm                Lowercase all elements
             _]I             Index of the current element in the 2nd input (-1 if not found)
                U>           Test 2: The index is non-negative
                                 i.e. current element is a member of the 2nd input
                  *C         If test 1 and test 2, drop the current element
                                 and go on mapping the next
                    iyj@     Fetch the corresponding element in the original input and return it as the mapped result
                                 This preserves the original case
Weijun Zhou
quelle
2

Perl 6 , 49 Bytes

->$_,+w{~.words.grep:{.lcw».lc||!(%){.lc}++}}

Probier es aus

Erweitert:

->              # pointy block lambda
  $_,           # first param 「$_」 (string)
  +w            # slurpy second param 「w」 (words)
{

  ~             # stringify the following (joins with spaces)

  .words        # split into words (implicit method call on 「$_」)

  .grep:        # take only the words we want

   {
     .lc        # lowercase the word being tested
               # is it not an element of
     w».lc      # the list of words, lowercased

     ||         # if it was one of the words we need to do a secondary check

     !          # Boolean invert the following
                # (returns true the first time the word was found)

     (
       %        # anonymous state Hash variable
     ){ .lc }++ # look up with the lowercase of the current word, and increment
   }
}
Brad Gilbert b2gills
quelle
2

Perl 5 , 50 48 Bytes

Beinhaltet +1für-p

Geben Sie die Zielzeichenfolge gefolgt von jedem Filterwort in separaten Zeilen in STDIN an:

perl -pe '$"="|";s%\b(@{[<>]})\s%$&x!$v{lc$1}++%iegx;chop';echo
This is a test Will this be correct Both will be removed
this
will
^D
^D

Das chopwird nur benötigt, um das nachgestellte Leerzeichen zu korrigieren, falls das letzte Wort entfernt wird

Nur der Code:

$"="|";s%\b(@{[<>]})\s%$&x!$v{lc$1}++%iegx;chop

Probieren Sie es online!

Tonne Hospel
quelle
1

JavaScript (ES6), 98 Byte

s=>a=>s.split` `.filter(q=x=>(q[x=x.toLowerCase()]=eval(`/\\b${x}\\b/i`).test(a)<<q[x])<2).join` `
ETHproductions
quelle
1

K4 , 41 Bytes

Lösung:

{" "/:x_/y@>y:,/1_'&:'(_y)~/:\:_x:" "\:x}

Beispiele:

q)k){" "/:x_/y@>y:,/1_'&:'(_y)~/:\:_x:" "\:x}["A cat called matt sat on a mat and wore a hat A cat called matt sat on a mat and wore a hat";("cat";"mat")]
"A cat called matt sat on a mat and wore a hat A called matt sat on a and wore a hat"

q)k){" "/:x_/y@>y:,/1_'&:'(_y)~/:\:_x:" "\:x}["Case for different case";enlist "case"]
"Case for different"

q)k){" "/:x_/y@>y:,/1_'&:'(_y)~/:\:_x:" "\:x}["the letters in the array are in a different case";enlist "In"]
"the letters in the array are a different case"

q)k){" "/:x_/y@>y:,/1_'&:'(_y)~/:\:_x:" "\:x}["5 times 5 is 25";(1#"5";1#"6")]
"5 times is 25"

Erläuterung:

Auf Leerzeichen aufteilen, beide Eingaben in Kleinbuchstaben schreiben, nach Übereinstimmungen suchen, alle bis auf das erste Vorkommen entfernen, die Zeichenfolge wieder zusammenfügen.

{" "/:x_/y@>y:,/1_'&:'(_y)~/:\:_x:" "\:x} / the solution
{                                       } / lambda with implicit x & y args
                                  " "\:x  / split (\:) on whitespace " "
                                x:        / save result as x
                               _          / lowercase x
                          ~/:\:           / match (~) each right (/:), each left (\:)
                      (_y)                / lowercase y
                   &:'                    / where (&:) each ('), ie indices of matches
                1_'                       / drop first of each result
              ,/                          / flatten
            y:                            / save result as y
         y@>                              / descending indices (>) apply (@) to y
      x_/                                 / drop (_) from x
 " "/:                                    / join (/:) on whitespace " "
Streetster
quelle
1

JavaScript (Node.js) , 75 Byte

f=(s,a)=>a.map(x=>s=s.replace(eval(`/\\b${x}\\b */ig`),s=>i++?"":s,i=0))&&s

Probieren Sie es online!

DanielIndie
quelle
1
Da dies keine rekursive Funktion ist, müssen Sie die nicht f=in Ihre Byteanzahl aufnehmen. Sie können auch ein Byte von currying die Parameter speichern, ersetzt (s,a)=>mit s=>a=>und dann mit dem Aufruf der Funktion f(s)(a).
Shaggy
@ Shaggy ja, aber es macht mir wirklich etwas aus, die Definition der Funktion zu Golf zu spielen, weil das Hauptgeschäft das Golfen des Körpers ist. Aber das ist ein guter Tipp :)
DanielIndie
1

JavaScript ES6, 78 Bytes

f=(s,a,t={})=>s.split` `.filter(w=>a.find(e=>w==e)?(t[w]?0:t[w]=1):1).join` `

Wie es funktioniert:

f=(s,a,t={})=> // Function declaration; t is an empty object by default
s.split` ` // Split the string into an array of words
.filter(w=> // Declare a function that, if it returns false, will delete the word
  a.find(e=>w==e) // Returns undeclared (false) if the word isn't in the list
  ?(t[w]?0 // If it is in the list and t[w] exists, return 0 (false)
    :t[w]=1) // Else make t[w] exist and return 1 (true)
  :1) // If the word isn't in the array, return true (keep the word for sure)
.join` ` // Rejoin the string
Ian
quelle
2
Willkommen bei PPCG! Da Sie den Funktionsnamen nicht ffür einen rekursiven Aufruf verwenden, ist eine unbenannte Funktion auch eine gültige Übermittlung. Sie können also zwei Bytes sparen, indem Sie das löschen f=.
Martin Ender
Willkommen bei PPCG! Leider schlägt dies fehl, wenn verschiedene Fälle betroffen sind.
Shaggy
Wenn das nicht so wäre, könntest du es auf 67 Bytes bringen
Shaggy
@MartinEnder Danke für den Tipp!
Ian
@Shaggy Das Verwenden des Eingabe-Arrays als Objekt ist eine interessante Idee, an die ich nicht gedacht hatte. Ich werde versuchen, das Fallproblem zu beheben.
Ian
0

PowerShell v3 oder höher, 104 Byte

Param($s,$w)$w|?{$_-and$s-match($r="\b$_(?: |$)")}|%{$h,$t=$s-split$r;$s="$h$($Matches.0)$(-join$t)"};$s

Auf Kosten von einem Byte, kann es in PS - 2.0 läuft durch Ersetzen $Matches.0mit $Matches[0].

Lange Version:

Param($s, $w)
$w | Where-Object {$_ -and $s -match ($r = "\b$_(?: |$)")} |    # Process each word in the word list, but only if it matches the RegEx (which will be saved in $r).
    ForEach-Object {                                            # \b - word boundary, followed by the word $_, and either a space or the end of the string ($)
        $h, $t = $s -split $r                                   # Split the string on all occurrences of the word; the first substring will end up in $h(ead), the rest in $t(ail) (might be an array)
        $s = "$h$($Matches.0)$(-join $t)"                       # Create a string from the head, the first match (can't use the word, because of the case), and the joined tail array
    }
$s                                                              # Return the result

Usage
Speichern als Whatever.ps1 und Anruf mit der Zeichenfolge und die Wörter als Argumente. Wenn mehr als ein Wort übergeben werden muss, müssen die Wörter in @ () eingeschlossen werden:

.\Whatever.ps1 -s "A cat called matt sat on a mat and wore a hat A cat called matt sat on a mat and wore a hat" -w @("cat", "mat")

Alternative ohne Datei (kann direkt in eine PS-Konsole eingefügt werden):
Speichern Sie das Skript als ScriptBlock (in geschweiften Klammern) in einer Variablen, rufen Sie dann die Invoke () -Methode auf, oder verwenden Sie sie mit Invoke-Command:

$f={Param($s,$w)$w|?{$_-and$s-match($r="\b$_(?: |$)")}|%{$h,$t=$s-split$r;$s="$h$($Matches.0)$(-join$t)"};$s}
$f.Invoke("A cat called matt sat on a mat and wore a hat A cat called matt sat on a mat and wore a hat", @("cat", "mat"))
Invoke-Command -ScriptBlock $f -ArgumentList "A cat called matt sat on a mat and wore a hat A cat called matt sat on a mat and wore a hat", @("cat", "mat")
user314159
quelle
0

Javascript, 150 Bytes

s=(x, y)=>{let z=new Array(y.length).fill(0);let w=[];for(f of x)(y.includes(f))?(!z[y.indexOf(f)])&&(z[y.indexOf(f)]=1,w.push(f)):w.push(f);return w}
aimorris
quelle
Abgesehen von den Problemen beim Golfen (einige Tipps finden Sie in den anderen JS-Lösungen), werden bei dieser Option die ersten Eingaben als eine Reihe von Wörtern verwendet und eine Reihe von Wörtern ausgegeben, die in der Herausforderungsspezifikation nicht zulässig sind. Es schlägt auch fehl, wenn verschiedene Fälle betroffen sind.
Shaggy
@Shaggy "Die Ausgabe kann entweder der Rückgabewert einer Funktion sein." Sieht so aus, als würde sie einen Wert von der Funktion zurückgeben.
Aimorris
0

Sauber , 153 142 138 134 Bytes

import StdEnv,StdLib,Text
@ =toUpperCase
$s w#s=split" "s
=join" "[u\\u<-s&j<-[0..]|and[i<>j\\e<-w,i<-drop 1(elemIndices(@e)(map@s))]]

Probieren Sie es online!

Definiert die Funktion $ :: String [String] -> Stringund tut so ziemlich wörtlich, was die Herausforderung beschreibt. Es findet und entfernt jedes Vorkommen nach dem ersten für jedes Zielwort.

Οurous
quelle
0

Retina, 46 37 Bytes

+i`(^|,)((.+),.*\3.* )\3( |$)
$2
.*,

-14 Bytes dank @Neil und +5 Bytes für einen Bugfix.

Eingabe im Format word1,word2,word3,sentence, da ich nicht sicher bin, wie man eine mehrzeilige Eingabe hat (wo die Eingaben unterschiedlich verwendet werden).

Erläuterung:

Probieren Sie es online aus.

+i`(^|,)((.+),.*\3.* )\3( |$)   Main regex to match:
+i`                              Enable case insensitivity
   (^|,)                          Either the start of the string, or a comma
        (                         Open capture group 2
         (                         Open capture group 3
          .+                        1 or more characters
            )                      Close capture group 3
             ,                     A comma
              .*                   0 or more characters
                \3                 The match of capture group 3
                  .*               0 or more characters, followed by a space
                     )            Close capture group 2
                      \3          The match of capture group 2 again
                        ( |$)     Followed by either a space, or it's the end of the string
$2                              And replace everything with:
                                 The match of capture group 2

.*,                             Then get everything before the last comma (the list)
                                 and remove it (including the comma itself)
Kevin Cruijssen
quelle
1
Wie geschrieben können Sie die erste Zeile zu +i`((.+),.*\2.* )\2( |$)und die zweite zu vereinfachen , $1aber ich stelle fest, dass Ihr Code often,he intended to keep ten geesetrotzdem fehlschlägt .
Neil
@Neil Danke für den -14 Golf, und den Fehler mit +1 behoben.
Kevin Cruijssen
... mit der Ausnahme, dass dies jetzt auf einem der ursprünglichen Testfälle fehlschlägt ...
Neil
@Neil Hoppla .. Wieder behoben für +4 Bytes.
Kevin Cruijssen
Nun, die gute Nachricht ist , ich denke , man kann benutzen \bstatt (^|,), aber die schlechte Nachricht ist , ich glaube , Sie brauchen \b\3\b(haben keinen passenden Testfall noch obwohl entwickelt).
Neil
0

Rot , 98 Bytes

func[s w][foreach v w[parse s[thru[any" "v ahead" "]any[to remove[" "v ahead[" "| end]]| skip]]]s]

Probieren Sie es online!

f: func [s w][ 
    foreach v w [                   ; for each string in the array
        parse s [                   ; parse the input string as follows:
            thru [                  ; keep everything thru: 
                any " "             ; 0 or more spaces followed by
                v                   ; the current string from the array followed by
                ahead " "           ; look ahead for a space
            ]
            any [ to remove [       ; 0 or more: keep to here; then remove: 
                " "                 ; a space followed by 
                v                   ; the current string from the array
                ahead [" " | end]]  ; look ahead for a space or the end of the string
            | skip                  ; or advance the input by one 
            ]
        ]
    ]
    s                               ; return the processed string 
]
Galen Ivanov
quelle
0

Schale , 13 Bytes

wüöVËm_Ṗ3+⁰ew

Nimmt eine Liste von Zeichenfolgen und eine einzelne Zeichenfolge als Argumente in dieser Reihenfolge. Es wird davon ausgegangen, dass die Liste frei von Duplikaten ist. Probieren Sie es online!

Erläuterung

wüöVËm_Ṗ3+⁰ew  Inputs: list of strings L (explicit, accessed with ⁰), string S (implicit).
               For example, L = ["CASE","for"], s = "Case for a different case".
            w  Split S on spaces: ["Case","for","a","different","case"]
 ü             Remove duplicates wrt an equality predicate.
               This means that a function is called on each pair of strings,
               and if it returns a truthy value, the second one is removed.
  öVËm_Ṗ3+⁰e    The predicate. Arguments are two strings, say A = "Case", B = "case".
           e    Put A and B into a list: ["Case","case"]
         +⁰     Concatenate with L: ["CASE","for","Case","case"]
       Ṗ3       All 3-element subsets: [["CASE","for","Case"],["CASE","for","case"],
                                        ["CASE","Case","case"],["for","Case","case"]]
  öV            Does any of them satisfy this:
    Ë            All strings are equal
     m_          after converting each character to lowercase.
                In this case, ["CASE","Case","case"] satisfies the condition.
               Result: ["Case","for","a","different"]
w              Join with spaces, print implicitly.
Zgarb
quelle
0

Min , 125 Bytes

=a () =b a 1 get =c a 0 get " " split
(:d (b d in?) ((c d in?) (d b append #b) unless) (d b append #b) if) foreach
b " " join

Die Eingabe erfolgt quotauf einem Stapel mit der Eingabezeichenfolge als erstes Element und einer quotder doppelten Zeichenfolgen als zweites Element, d. H

("this sentence has no matches" ("ten" "cheese"))
Panda0nEarth
quelle
0

Python 3 , 168 Bytes

def f(s,W):
 s=s.split(" ");c={w:0for w in W}
 for w in W: 
  for i,v in enumerate(s):
   if v.lower()==w.lower():
    c[w]+=1
    if c[w]>1:s.pop(i)
 return" ".join(s)

Probieren Sie es online!

Trelzevir
quelle
0

AWK , 120 Bytes

NR%2{for(;r++<NF;)R[tolower($r)]=1}NR%2==0{for(;i++<NF;$i=$(i+s))while(R[x=tolower($(i+s))])U[x]++?++s:i++;NF-=s}NR%2==0

Probieren Sie es online!

Der Teil "Whitespace entfernen" machte dies etwas schwieriger als ich zuerst dachte. Wenn Sie ein Feld auf setzen "", wird ein Feld entfernt, es bleibt jedoch ein zusätzliches Trennzeichen übrig.

Die TIO-Verbindung verfügt über 28 zusätzliche Bytes, um mehrere Einträge zuzulassen.

Die Eingabe erfolgt über 2 Zeilen. Die erste Zeile ist die Liste der Wörter und die zweite Zeile ist der "Satz". Beachten Sie, dass "word" und "word" nicht als identisch mit der angehängten Interpunktion angesehen werden. Interpunktionsanforderungen würden dies wahrscheinlich zu einem noch spaßigeren Problem machen.

Robert Benson
quelle
0

Ruby , 63 61 60 59 Bytes

->s,w{w.any?{|i|s.sub! /\b(#{i}\b.*) #{i}\b/i,'\1'}?redo:s}

Probieren Sie es online!

Eine kürzere Version, bei der zwischen Groß- und Kleinschreibung unterschieden wird und die ~ alle 10-15- mal aufgrund von Zufälligkeiten fehlschlägt (37 Byte)

->s,w{s.uniq{|i|w.member?(i)?i:rand}}
Asone Tuhid
quelle
0

Python 2 , 140 Bytes

from re import*
p='\s?%s'
S,A=input()
for a in A:S=sub(p%a,lambda s:s.end()==search(p%a,S,flags=I).end()and s.group()or'',S,flags=I)
print S

Probieren Sie es online!

Erläuterung:

re.sub(..)kann als Argument eine Funktion anstelle einer Ersatzzeichenfolge verwenden. Also hier haben wir etwas schickes Lambda. Für jedes Auftreten eines Musters wird eine Funktion aufgerufen und ein Objekt an diese Funktion übergeben - das Match-Objekt. Dieses Objekt enthält Informationen zum Fundierten Vorkommen. Ich interessiere mich für einen Index dieses Ereignisses, der von start()oder über eine end()Funktion abgerufen werden kann. Letzteres ist kürzer, so dass es verwendet wird.

Um das Ersetzen des ersten Vorkommens eines Wortes auszuschließen, habe ich eine andere Regex-Suchfunktion verwendet, um genau das erste zu erhalten und dann die Indizes zu vergleichen, wobei dieselbe verwendet wurde end()

Flagge re.Iist eine Kurzversion vonre.IGNORECASES

Totes Opossum
quelle