2015-03-19 12 views
7

Ho uno stringa simile a questa:Come trovare una stringa duplicata con Pattern Matching?

[13:41:25] [100:Devnull]: 01:41:20, 13:41:21> |Hunit:Player-3693-07420299:DevnullYour [Chimaera Shot] hit |Hunit:Creature-0-3693-1116-3-87318-0000881AC4:Dungeoneer's Training DummyDungeoneer's Training Dummy 33265 Nature. 

Nel caso in cui si chiedono, è da World of Warcraft.

mi piacerebbe finire con qualcosa di simile:

[13:41:25] [100:Devnull]: 01:41:20, 13:41:21> Your [Chimaera Shot] hit Dungeoneer's Training Dummy 33265 Nature. 

Se si nota, "Formazione fittizia del Dungeoneer" viene stampato due volte. Sono riuscito a sbarazzarsi del primo "| Hunit" parte con qualcosa di simile:

str = "[13:41:25] [100:Devnull]: 01:41:20, 13:41:21> |Hunit:Player-3693-07420299:DevnullYour [Chimaera Shot] hit |Hunit:Creature-0-3693-1116-3-87318-0000881AC4:Dungeoneer's Training DummyDungeoneer's Training Dummy 33265 Nature." 
str = string.gsub(str, "|Hunit:.*:.*Your", "Your") 

che restituisce questo:

print(str) # => [13:41:25] [100:Devnull]: 01:41:20, 13:41:21> Your [Chimaera Shot] hit |Hunit:Creature-0-3693-1116-3-87318-0000881AC4:Dungeoneer's Training DummyDungeoneer's Training Dummy 33265 Nature. 

ho quindi aggiungere un secondo gsub:

str = string.gsub(str, "|Hunit:.*:", "") 
print(str) # => [13:41:25] [100:Devnull]: 01:41:20, 13:41:21> Your [Chimaera Shot] hit Dungeoneer's Training DummyDungeoneer's Training Dummy 33265 Nature. 

Ma la doppia stringa "Dungeoneer's Training Dummy" viene ripetuta, ovviamente.

Come si può eliminare la stringa duplicata? Questa stringa può essere qualsiasi altra cosa, in questo caso è "Dungeoneer's Training Dummy", ma può essere il nome di qualsiasi altro target.

risposta

4

si può provare qualcosa di simile:

str = "[13:41:25] [100:Devnull]: 01:41:20, 13:41:21> Your [Chimaera Shot] hit Dungeoneer's Training DummyDungeoneer's Training Dummy 33265 Nature." 
-- find a string that starts with 'hit', has some number of non-digits 
-- and ends with one or more digit and one or more characters. 
-- these characters will be "captured" into three strings, 
-- which are then passed to the "replacement" function. 
-- the returned result of the function replaces the value in the string. 
str = str:gsub("(hit%s+)([^%d]+)(%d+.+)", function(s1, s2, s3) 
    local s = s2:gsub("%s+$","") -- drop trailing spaces 
    if #s % 2 == 0 -- has an even number of characters 
    and s:sub(0, #s/2) -- first half 
    == -- is the same 
    s:sub(#s/2 + 1) -- as the second half 
    then -- return the second half 
     return s1..s:sub(#s/2 + 1)..' '..s3 
    else 
     return s1..s2..s3 
    end 
    end) 
print(str) 

Questo stampa: [13:41:25] [100:Devnull]: 01:41:20, 13:41:21> Your [Chimaera Shot] hit Dungeoneer's Training Dummy

Questo codice tenterà di estrarre il nome della destinazione e verificare se il nome è un duplicato completo. Se la corrispondenza fallisce, restituisce la stringa originale.

+0

Questo lo fa, anche se ho ancora bisogno della coda "33265 Natura". Ti dispiacerebbe spiegare cosa succede nella funzione che hai usato? Se non è un problema. – user3209270

+0

Dopo aver rimosso 33265 Nature, la funzione controlla se la stringa corrente può essere divisa in due metà e controllare se queste due metà sono uguali. Aggiungerò altri commenti ... –

+0

Aggiorna la soluzione per mantenere "33265 Natura" al suo interno. –