1. I'm working on a project that takes system chat messages that contain a hyperlink for a player and pulls the player's name from the message. I've looked at a number of different sites doing my best to figure out the patterns and I thought I had come up with a solution. Using one of my characters as an example, here is my basic code.

     local hyperlink = "|Hplayer :Roheit|h[Roheit]|h"
     local _,_,name = string.find(hyperlink,"|Hplayer :(%a+)|?h?[?%a+]?|?h?")
     print(name)
    

    This prints "Roheit". When I tested the code with my character Räude, all I get is "R". I know it has to do with "ä" but I can't figure out how to find the full name with a pattern.

    Once I get this worked out, I'll be able to cut one of my mods down drastically. Any help provided will be greatly appreciated.

  2. %a won't match ä because its not an alphabetic ASCII character, based on the character classes. What you can use is [^|] which means 'any character that isn't the pipe character' and use + on that.

  3. Thank you so much. That worked beautifully. This pattern stuff gives me some serious brain pain. :)

  4. Well that worked in wowlua, but when I put the code into my mod, it doesn't seem to work the way I was expecting. Here is the code I am using in the mod once my frame registers the event.

     if event == "CHAT_MSG_SYSTEM" then
        local total_friends = GetNumFriends()
    
        if (social_info:find("online") ~= nil) then
           print("Online found.")
           local _,_,hyperlink,_ = string.find(social_info,"(%S+)[%s]*(.*)")
           print(hyperlink .. " found.")
           local _,_,playername = string.find(hyperlink,"|Hplayer :([^|]+)|?h?[?[^|]+]?|?h?")
           for i=1,total_friends do
              name,_,_,_,_,_,_,_ = GetFriendInfo(i)
              if playername == name then
                 print(playername .. " found! ONLINE!")
                 social_info = " "
                 break
              end
           end
        end
     end
    

    "Online found." and "[hyperlink] found." print as expected but the player's name is not pulled form the hyperlink. Is there something I'm missing?

    I have another question that could make all this unnecessary . I found the WoW Constants/Errors page on wowpedia. Is it possible to find ERRFRIENDONLINE_SS specifically? If it is possible, can I also find "%s" inside "|Hplayer :%s|h[%s]|h has come online."?

  5. You don't need Wowpedia to find those, they're all in GlobalStrings.lua in the FrameXML code. Using them directly is not completely trivial to make them work on all locales. There is a library called Deformat that can take a global string like that and turn it into a pattern that you can use to re-extract the arguments out of the actual message.

    Additionally, if the string you want to match is:

     "|Hplayer :%s|h[%s]|h has come online."
    

    Then you should be able to extract it with:

     "|Hplayer :%s|h%[%s%]|h has come online%."
    
  6. I looked through the book reading about GlobalStrings and I downloaded the library LibDeformat-3.0. I understand how the GlobalStrings work now after doing a couple simple print() tests in wowlua

    print(ERR_FRIEND_ONLINE_SS)

    and I can see how that will be used in LibDeformat,

    LibDeformat(social_msg, "|Hplayer :%s|h[%s]|h has come online.") == "playername", "playername"

    I don't understand how to use the global string with LibDeformat though. If I use "|Hplayer :%s|h%[%s%]|h has come online%." will it work regardless of localization? Or do I use the following:

    LibDeformat(social_msg, ERR_FRIEND_ONLINE_SS) == "playername", "playername"

    Thank you for your time and patience.

  7. The last is correct if you want this to work for all locales, that's the beauty (and complexity) of LibDeformat. You may be able to 'reverse' format strings for very simple cases, but if you consider non-English locales where even the order of the arguments may be reversed (I discuss this in the book, where the actor and object are sometimes reversed) then you need LibDeformat or something like it in order to work correctly. Using the symbolic constant name is the correct way to make this work.