【问题标题】:How to find a duplicate string with Pattern Matching?如何使用模式匹配找到重复的字符串?
【发布时间】:2015-05-23 03:59:47
【问题描述】:

我有一个类似这样的字符串:

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

如果你想知道,它来自魔兽世界。

我想以这样的方式结束:

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

如果您注意到,“Dungeoneer's Training Dummy”会打印两次。我已经设法摆脱了第一个“|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”字符串。

我怎样才能摆脱重复的字符串?这个字符串可以是其他任何东西,在本例中是“Dungeoneer's Training Dummy”,但它可以是任何其他目标的名称。

【问题讨论】:

    标签: lua lua-patterns world-of-warcraft


    【解决方案1】:

    你可以试试这样的:

    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

    此代码将尝试提取目标的名称并检查该名称是否完全重复。如果匹配失败,则返回原始字符串。

    【讨论】:

    • 就是这样,虽然我仍然需要尾随的“33265 Nature.”。你介意解释一下你使用的函数发生了什么吗?如果不麻烦的话。
    • 33265 Nature 被移除后,该函数检查当前字符串是否可以分成两半,并检查这两半是否相同。我会添加更多的 cmets...
    • 更新解决方案以保留33265 Nature
    • 哦,我明白了。偶数个字符表明它是重复的。聪明的。非常感谢!
    • 对;我认为如果有人不熟悉[^] 会很有用,但%D 肯定更短。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 2018-05-30
    相关资源
    最近更新 更多