2015-03-19 5 views
7

У меня есть строка, похожее на это:Как найти повторяющуюся строку с совпадением шаблонов?

[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. 

В случае вы удивляетесь, это из World Of Warcraft.

Я хотел бы закончить с чем-то вроде этого:

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

Если вы заметили, "Training Dummy Dungeoneer в" печатается дважды. Я сумел избавиться от первого "| Hunit" часть с чем-то вроде этого:

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

Который возвращает это:

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. 

Затем я добавить второй 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. 

Но двойная строка «Dungeoneer's Training Dummy» повторяется, очевидно.

Как я мог избавиться от дублированной строки? Эта строка может быть чем угодно, в этом случае это «Dummy's Dummy's Dummy», но это может быть название любой другой цели.

ответ

4

Вы можете попробовать что-то вроде этого:

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) 

Печатается: [13:41:25] [100:Devnull]: 01:41:20, 13:41:21> Your [Chimaera Shot] hit Dungeoneer's Training Dummy

Этот код будет пытаться извлечь имя цели и проверить, является ли имя полный дубликат. Если совпадение не выполняется, возвращается исходная строка.

+0

Это делает, хотя мне все еще требуется конечная «Природа 33265». Не могли бы вы объяснить, что происходит в вашей функции? Если это не так много. – user3209270

+0

После удаления 33265 Nature функция проверяет, можно ли разбить текущую строку на две половины и проверить, одинаковы ли эти две половины. Я добавлю дополнительные комментарии ... –

+0

Обновите решение, чтобы сохранить в нем '33265 Nature'. –

Смежные вопросы