2015-03-19 12 views
7

Ich habe eine Zeichenfolge wie folgt aus:Wie finde ich eine doppelte Zeichenkette mit 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. 

Falls Sie sich fragen, es ist von World of Warcraft.

ich mit so etwas wie das enden würde:

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

Wenn Sie bemerken, ist „Dungeoneer Trainings Dummy“ zweimal gedruckt. Ich habe es geschafft, von der ersten loszuwerden "| hunit" wie folgt mit etwas Portion:

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

Welche dies zurück:

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. 

ich dann ein zweites gsub hinzufügen:

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. 

Aber die doppelte "Dungeoneer's Training Dummy" Saite wird offensichtlich wiederholt.

Wie kann ich die doppelte Zeichenfolge loswerden? Diese Zeichenfolge kann alles andere sein, in diesem Fall ist "Dungeoneers Training Dummy", aber es kann der Name eines anderen Ziels sein.

Antwort

4

Sie können so etwas wie dies versuchen:

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) 

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

Dieser Code wird versuchen, den Namen des Ziels zu extrahieren und prüfen, ob der Name ein volles Duplikat ist. Wenn die Übereinstimmung fehlschlägt, wird die ursprüngliche Zeichenfolge zurückgegeben.

+0

Das tut es, obwohl ich immer noch die abschließende "33265 Nature.". Würde es Ihnen etwas ausmachen zu erklären, was in der von Ihnen verwendeten Funktion passiert? Wenn es nicht viel Ärger ist. – user3209270

+0

Nachdem 33265 Nature entfernt wurde, überprüft die Funktion, ob der aktuelle String in zwei Hälften aufgeteilt werden kann und ob diese beiden Hälften gleich sind. Ich werde weitere Kommentare hinzufügen ... –

+0

Aktualisieren Sie die Lösung, um '33265 Nature' darin zu behalten. –