Results 1 to 23 of 23

Thread: Need a way to parse tags that contain parameters

  1. #1

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Need a way to parse tags that contain parameters

    So my game is getting polished up and there's a thing I've been avoiding but thinking about almost the entire time I've been working on it.

    I've posted my code for the content editor in code bank several times.

    It's a text-based game that can contain tags such as <He/She>, <Him/Her>, <Player First Name>, etc.

    They're all simple replacements.

    If LCase$(Token)="<player first name>" then

    sReturn = Player.FirstName

    end if

    The problem is when I want do something with parameters such as <PlaySound: BigGong>, <PlaySound: TireSqueal>, <PlaySound: PeopleScreaming>, etc.

    ----------------------

    Your friend opens the door to let you into his apartment.

    "I have something to show you."

    He points at the biggest gong you have ever seen. It's suspended a foot from the floor and almost reaches the ceiling.

    "Cool, huh?"
    <PlaySound: BigGong>
    'If you say so. Why?'

    ----------------------

    Part of the problem is that anything I use for brackets can also just be used as text.

    So the text could contain something like, "Your friend points over there -> <PlaySound: BigGong> (sorry I couldn't come up with a better example.

    I can parse the tag once I have it. The problem is how to pull it out of the text. Because partial tags can be anywhere it would take a lot more smarts than I have to parse it and figure out which tags go with which.

    Also too, I don't get regular expressions at all so it will need it to be kind of specific and not just a general idea if that's how you think I should do it.

    Thanks.

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,268

    Re: Need a way to parse tags that contain parameters

    Quote Originally Posted by cafeenman View Post

    Also too, I don't get regular expressions at all so it will need it to be kind of specific and not just a general idea if that's how you think I should do it.

    Thanks.
    But Regex IS the factual "Tool" to use here, so you have a choice to make:
    1) Do everything by yourself (with all problems it involves)
    2) Buckle down and learn Regex

    Here a Regex for your example above: https://regex101.com/r/bGijvq/2
    Returns "BigGong" in the first Capture-Group

    Of course, this is quick and dirty, as i haven't covered all possible bases (What to do if there is a second match later on etc.)
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    Quote Originally Posted by Zvoni View Post
    But Regex IS the factual "Tool" to use here, so you have a choice to make:
    1) Do everything by yourself (with all problems it involves)
    2) Buckle down and learn Regex

    Here a Regex for your example above: https://regex101.com/r/bGijvq/2
    Returns "BigGong" in the first Capture-Group

    Of course, this is quick and dirty, as i haven't covered all possible bases (What to do if there is a second match later on etc.)
    I'm not anti-regex. I just find it really hard to use but it is probably the exact tool i need.

    The system processes each tag as it comes so that's not a problem. It can have as many consecutive tags in the same message as it wants.

    For example.

    (tags like <adverb>,<girlname>, etc. pick one at random from lookup tables.)

    Code:
    "Wow. That's a <adverb> <adjective> <noun>." ' Returns random everything. That's a frightfully smart grape."
    The only tag that is "saved" for later is the <die> tag which lets the thing that got you killed finish before it kills you. Otherwise it would skip out as soon as it found <die> and the rest of the text would never play.

    So this is what I'm doing?

    Code:
    Select Case Token
    
        Case "<PlaySound:\s*(\w+)\s*>"
    
            ' Find what the parameter is here or send to a specialized function.
    
    End Select

    Thanks.
    Last edited by cafeenman; Nov 13th, 2025 at 03:04 AM.

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,268

    Re: Need a way to parse tags that contain parameters

    Quote Originally Posted by cafeenman View Post
    So this is what I'm doing?

    Code:
    Select Case Token
    
        Case "<PlaySound:\s*(\w+)\s*>"
    
            ' Find what the parameter is here or send to a specialized function.
    
    End Select

    Thanks.
    Close. You are comparing your Token to the Pattern

    So "aircoding" your code above:
    Code:
    Select Case True
    
        Case Token Like "<PlaySound:*>"
    
            Execute Regex With Pattern "<PlaySound:\s*(\w+)\s*>"
            If Return="BigGong" Then PlayBigGongSound
            If Return="TireSqueal" Then PlayTireSquealSound
    
    End Select
    To use the Regex-Engine you need a Reference to "Scripting Runtime" (or whatever it's called).
    Add it, hit F2 and start exploring.
    There should also be enough examples on the net to guide you through the Regex-Object/Engine.
    What Pattern to use is another story, which hasn't anything to do with the Engine used.

    There should be enough people here to help you out if you're stuck
    Last edited by Zvoni; Nov 13th, 2025 at 08:31 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  5. #5

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    Thank you very much. You may have just improved my game by approximately a lot.


  6. #6

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    OK, one more question. How does one "execute regex"?

  7. #7
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,268

    Re: Need a way to parse tags that contain parameters

    Quote Originally Posted by cafeenman View Post
    OK, one more question. How does one "execute regex"?
    That's what i meant with "You need a Reference to Scripting Runtime" and "Explore the Object-Catalogue" and "There should be enough examples on the net how to use it"

    Though i just found out, that Microsoft is going to "retire" vbscript.dll (Which includes the Regex-Engine)
    https://nolongerset.com/end-of-regex-support-in-vba/

    So depending on how long you want to support it, you might have to look for alternatives
    https://www.aivosto.com/regexpr.html


    "Reference"= to vbscript.dll (It's not the "Scripting Runtime", Sorry)
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  8. #8

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    OK, I understand I need the scripting runtime. I think it's already in the project for file handling.

    Edit: Oops. It's the File Scripting Runtime in my project, not vbscript.

    Won't any references be included in the setup package including the vbscript dll? If so then the user doesn't need to have it but I do.

    Code:
    Select Case True
    
        Case Token Like "<PlaySound:*>"
    
            Execute Regex With Pattern "<PlaySound:\s*(\w+)\s*>"
            If Return="BigGong" Then PlayBigGongSound ' <---- how am I getting this Return?
            If Return="TireSqueal" Then PlayTireSquealSound
    
    End Select
    Also too I found this: https://binaryworld.net/Main/CodeDetail.aspx?CodeId=122

    Code:
    Function GetWords(ByVal Text As String, Optional DiscardDups As Boolean) As _
      Collection
      Dim re As New RegExp
      Dim ma As Match
      
      ' the following pattern means that we're looking for a word character (\w)
      ' repeated one or more times (the + suffix), and that occurs on a word
      ' boundary (leading and trailing \b sequences)
      re.Pattern = "\b\w+\b"
      ' search for *all* occurrences
      re.Global = True
      
      ' initialize the result
      Set GetWords = New Collection
      
      ' we need to ignore errors, if duplicates are to be discarded
      On Error Resume Next
      
      ' the Execute method does the search and returns a MatchCollection object
      For Each ma In re.Execute(Text) ' <---- Does this return the actual text found by regex?
        If DiscardDups Then
          ' if duplicates are to be discarded, we just add a key to the
          ' collection item
          ' and the Add method will do the rest
          GetWords.Add ma.Value, ma.Value
        Else
          ' otherwise just add to the result
          GetWords.Add ma.Value
        End If
      Next
      
    End Function
    Also too, I apologize because my code has been running a test for several hours that I don't want to start over so I can't really play with any of this right now unless I want to begin a whole test app.

    Once it's done I'll start trying some things and maybe have better questions or have my answers.

    Thanks again.
    Last edited by cafeenman; Nov 13th, 2025 at 09:49 AM.

  9. #9
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,268

    Re: Need a way to parse tags that contain parameters

    Quote Originally Posted by cafeenman View Post
    OK, I understand I need the scripting runtime. I think it's already in the project for file handling.

    Edit: Oops. It's the File Scripting Runtime in my project, not vbscript.

    Won't any references be included in the setup package including the vbscript dll? If so then the user doesn't need to have it but I do.

    Code:
    Select Case True
    
        Case Token Like "<PlaySound:*>"
    
            Execute Regex With Pattern "<PlaySound:\s*(\w+)\s*>"
            If Return="BigGong" Then PlayBigGongSound ' <---- how am I getting this Return?
            If Return="TireSqueal" Then PlayTireSquealSound
    
    End Select
    Also too I found this: https://binaryworld.net/Main/CodeDetail.aspx?CodeId=122

    Code:
    Function GetWords(ByVal Text As String, Optional DiscardDups As Boolean) As _
      Collection
      Dim re As New RegExp
      Dim ma As Match
      
      ' the following pattern means that we're looking for a word character (\w)
      ' repeated one or more times (the + suffix), and that occurs on a word
      ' boundary (leading and trailing \b sequences)
      re.Pattern = "\b\w+\b"
      ' search for *all* occurrences
      re.Global = True
      
      ' initialize the result
      Set GetWords = New Collection
      
      ' we need to ignore errors, if duplicates are to be discarded
      On Error Resume Next
      
      ' the Execute method does the search and returns a MatchCollection object
      For Each ma In re.Execute(Text) ' <---- Does this return the actual text found by regex?
        If DiscardDups Then
          ' if duplicates are to be discarded, we just add a key to the
          ' collection item
          ' and the Add method will do the rest
          GetWords.Add ma.Value, ma.Value
        Else
          ' otherwise just add to the result
          GetWords.Add ma.Value
        End If
      Next
      
    End Function
    Also too, I apologize because my code has been running a test for several hours that I don't want to start over so I can't really play with any of this right now unless I want to begin a whole test app.

    Once it's done I'll start trying some things and maybe have better questions or have my answers.

    Thanks again.
    The "Result"/"Return" is in the "ma"-Object in your code-sample, there it's the "Value"-property

    "ma" is Dim-ed as "Match"
    Re.Execute returns a MatchCollection, in which "ma" is a Member of

    You could also Dim a Variable as MatchCollection, and just
    do a
    Code:
    Dim mc as MatchCollection
    re.Pattern=MyPattern
    'All other Properties
    Set mc=re.Execute(MyToken)
    ...and then set a Breakpoint on the Set mc -line (or the line after it), and look at everything in the Watch-Window. Explore it.
    I'm sure you'll get the hang of it "where is what" pretty quickly, nevermind when you find the "Result" you are looking for ("BigGong")

    Remember: The Result of the Execute is a (Match-)Collection, and i do hope you know how to access members of a Collection
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  10. #10

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    That brings me a new problem though. If it's finding the regex, then how do I find the entire token to remove it from the displayed text?

    I might have to do two sweeps or something. Not sure how I'll resolve that but first get the regex working then work on the details of any other associated messes.

    Thanks again.

    No problem with collections. I do know how to use them. They're pretty extensive throughout the game.

  11. #11

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    OK, I can't find vbscript.dll anywhere in references. Maybe it's already gone? As is I can't even get started testing.

    Totally lost.

    Edit: Never mind. I found it. Microsoft VBScript Regular Expressions (a couple of choices - I selected the newest one on my system 5.5).

    The regex string you wrote works great. Now I just have to figure out how to find all the possible tags, do whatever with them (that's the easy part) and replace the whole tag with an empty string.
    Last edited by cafeenman; Nov 13th, 2025 at 11:33 AM.

  12. #12
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    Re: Need a way to parse tags that contain parameters

    You can replace matches using the Replace method of the RegExp object:

    Code:
       Dim re As New RegExp
       
       re.Pattern = "<PlaySound:\s*(\w+)\s*>"
       Debug.Print "New String: " & re.Replace("This is a test<PlaySound: ABCDEFG>. Done :)", vbNullString)

  13. #13

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    Well... I was just about to post my convoluted way of doing the same thing which feels really hacked to me. Since I wrote it I'm going to post it but if this does what you say, obviously I'll replace it.

    Also, I only have a few tags that would use parameters at the moment. But instead of doing what I did here I'm going to make it more general so I can send the tags I'm looking for to one procedure instead of a procedure for each one.

    Then it will return whatever I need which I haven't gotten that far yet.

    This code is working though:

    This is the raw input:

    Code:
    Word before <PlaySound: BigGong> <PlaySound: TiresSquealing> word after.
    This is the output to the user:

    Code:
    	<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>
    	* The Sharply Prudent Histories of Sterling Soupforkinöv *
    	
    	  Chapter 807: Test
    	<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>
    
    	Word before word after.
    	<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>> fin’
    This is the whole code:

    Code:
    Private Function ProcessRegEx(ByRef Token As String) As String
    Dim m_RegEx As RegExp
    Dim colMatches As MatchCollection
    Dim m_Match As Match
    Dim s As String
    Dim sReturn As String
    
    ' Example: Send " Word before <PlaySound: BigGong> <PlaySound: TiresSquealing> word after."
    ' Return should be "Word before word after."
    
    ProcessRegEx = Token
    
    Set m_RegEx = New RegExp
    
    With m_RegEx
    
      .IgnoreCase = True
      .Global = True
      .Pattern = "<PlaySound:\s*(\w+)\s*>"
    
    End With
    
    Set colMatches = m_RegEx.Execute(Token)
    
    sReturn = Token
    
    For Each m_Match In colMatches
    
      ' m_Match.Value(1) = <PlaySound: BigGong>
      ' m_Match.Value(2) = <PlaySound: TiresSquealing>
    
      s = GetTagParameter("PlaySound:", m_Match.Value) ' Returns BigGong (first loop) and TiresSquealing (second loop).
    
      sReturn = StripTag(sReturn, "<PlaySound")
    
    Next
    
    ProcessRegEx = sReturn
    
    End Function
    
    Private Function GetTagParameter(ByRef Command As String, ByRef Value As String)
    Dim s As String
    
    s = StripBrackets(Value)
    
    s = Trim$(Replace(s, Command, vbNullString, 1, -1, vbTextCompare))
    
    GetTagParameter = s
    
    End Function
    
    Private Function StripTag(ByRef Token As String, ByRef Tag As String) As String
    Dim s As String
    Dim nPos As Long
    Dim nEndPos As Long
    Dim n As Long
    Dim s1 As String
    Dim s2 As String
    
    StripTag = Token
    
    nPos = InStr(1, Token, Tag, vbTextCompare)
    
    If nPos = 0 Then Exit Function
    
    For n = nPos + 1 To Len(Token)
    
      If Mid$(Token, n, 1) = ">" Then
    
        nEndPos = n
    
        Exit For
      
      End If
    
    Next n
    
    If nEndPos = 0 Then Exit Function
    
    s1 = Left$(Token, nPos - 1)
    s1 = RTrim$(s1)
    
    s2 = Right$(Token, Len(Token) - nEndPos)
    s2 = LTrim$(s2)
    
    If s1 <> vbNullString And s2 <> vbNullString Then
    
      StripTag = s1 & " " & s2
    
    Else
    
      StripTag = s1 & s2
    
    End If
    
    End Function
    Last edited by cafeenman; Nov 13th, 2025 at 12:48 PM.

  14. #14
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    Re: Need a way to parse tags that contain parameters

    Something like this could process all of your token commands and strip them in one method:

    Code:
    Public Function ProcessTokenCommands(ByVal p_Token As String) As String
       Dim lo_Matches As MatchCollection
       Dim lo_Match As Match
       Dim l_CmdKey As String
       Dim l_CmdValue As String
       
       If mo_Regex Is Nothing Then Set mo_Regex = New RegExp
       
       With mo_Regex
          .IgnoreCase = -True
          .Global = True
          .Pattern = "<(\w+):\s*(\w+)\s*>" ' Match commands and values for processing
       End With
       
       Set lo_Matches = mo_Regex.Execute(p_Token)
       
       For Each lo_Match In lo_Matches
          ' Pull Command and CommandValue from match
          l_CmdKey = LCase$(lo_Match.SubMatches(0))
          l_CmdValue = LCase$(lo_Match.SubMatches(1))
          
          ' Process command & value
          Select Case l_CmdKey
          Case "playsound"
             ' Play appropriate sound
             
             Select Case l_CmdValue
             Case "biggong"
                ' Play BigGong Sound
             
             Case "tiressquealing"
                ' Play TiresSquealing Sound
             
             Case Else
                ' Unknown sound!!
                Debug.Assert False
                
             End Select
          
          Case Else
             ' Unknown command!!
             Debug.Assert False
          End Select
       Next
       
       ' Return token with commands removed
       ProcessTokenCommands = mo_Regex.Replace(p_Token, vbNullString)
    End Function

  15. #15

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    The only problem is that I'll probably want to process them as I go.

    For example, say I have a long block of text that has several of these in it.

    If I loop through and find them all then I have the choice of executing them before or after I display the text but not in the middle.

    If I find them one at a time, strip them out and keep doing that until I don't find any more then I can process them as I find them.

    So the way I did it does not do that. The loop would have to be outside the processregex thing and then be called over and over.

    I could probably make m_RegEx a module level variable and create it once instead of every time I enter the procedure. Then just set the pattern when I enter.

    So I'd be sending the Text, a tag and an empty string.

    The string would return the parameter value and the function would return the modified Text.

    I'm working on all that now.

    Also, it all depends on RegEx returning values in the order they appear in the text. I assume that's what it does.

    To summarize.

    Send text to find one tag at a time.

    If one is found, strip it out, return the values and the modified string.

    Look for next tag and repeat until no tag is found then move along to the next thing.

  16. #16
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    Re: Need a way to parse tags that contain parameters

    You could put the matching in a class and with an event that is raise at every match (this event could also have a StopProcessing parameter that would allow your host form to stop processing commands at any time if necessary). For example, the following CTokenCmdProcessor class:

    Code:
    Option Explicit
    
    Public Event ProcessCommand(ByVal p_Key As String, ByVal p_Value As String, ByVal p_TextBefore As String, ByVal p_TextAfter As String, ByRef p_Stop As Boolean)
    
    Private mo_Regex As RegExp
    
    Public Function ProcessTokenCommands(ByVal p_Token As String) As String
       Dim lo_Matches As MatchCollection
       Dim lo_Match As Match
       Dim l_CmdKey As String  ' Matched command key
       Dim l_CmdValue As String   ' Matched command value
       Dim l_Stop As Boolean   ' If TRUE stop processing token for commands
       Dim l_TextBefore As String ' Text before the matched command
       Dim l_TextAfter As String  ' Text after the matched command
       
       With mo_Regex
          .IgnoreCase = -True
          .Global = True
          .Pattern = "<(\w+):\s*(\w+)\s*>" ' Match commands and values for processing
       End With
       
       Do
          Set lo_Matches = mo_Regex.Execute(p_Token)
          
          If lo_Matches.Count > 0 Then
             Set lo_Match = lo_Matches.Item(0)
             
             ' Pull Command and CommandValue from match
             l_CmdKey = LCase$(lo_Match.SubMatches(0))
             l_CmdValue = LCase$(lo_Match.SubMatches(1))
             
             l_TextBefore = vbNullString
             l_TextAfter = vbNullString
             l_TextBefore = Mid$(p_Token, 1, lo_Match.FirstIndex)
             l_TextAfter = Mid$(p_Token, 1 + lo_Match.FirstIndex + lo_Match.Length)
             
             RaiseEvent ProcessCommand(l_CmdKey, l_CmdValue, _
                                       l_TextBefore, _
                                       l_TextAfter, _
                                       l_Stop)
             
             ProcessTokenCommands = ProcessTokenCommands & l_TextBefore
             p_Token = l_TextAfter
          End If
       Loop While (lo_Matches.Count > 0) And Not l_Stop
       
       ' Return token with commands removed
       ProcessTokenCommands = ProcessTokenCommands & p_Token
    End Function
    
    Private Sub Class_Initialize()
       Set mo_Regex = New RegExp
    End Sub
    Then in your main app form:

    Code:
    Option Explicit
    
    Private WithEvents mo_Processor As CTokenCmdProcessor
    
    Private Sub Form_Click()
       Set mo_Processor = New CTokenCmdProcessor
       Debug.Print "Token Stripped of Commands (unless cancelled mid-way): " & mo_Processor.ProcessTokenCommands("Word before <PlaySound: BigGong> <PlaySound: TiresSquealing> word after.")
    End Sub
    
    Private Sub mo_Processor_ProcessCommand(ByVal p_Key As String, ByVal p_Value As String, ByVal p_TextBefore As String, ByVal p_TextAfter As String, ByRef p_StopProcessing As Boolean)
       Debug.Print "Processing Command: " & p_Key, "Value: " & p_Value
       Debug.Print "Text Before Command: """ & p_TextBefore & """"
       Debug.Print "Text After Command: """ & p_TextAfter & """"
       Debug.Print
       
       Select Case p_Key
       Case "playsound"
          Select Case p_Value
          Case "biggong"
             ' Play big gong sound
             Debug.Print "PLAY BIG GONG"
             
          Case "tiressquealing"
             ' Play tires squealing sound
             Debug.Print "PLAY TIRES SQUEALING"
          
          Case Else
             ' Uhoh! Unhandled sound parameter!! Check for typo
             Debug.Assert False
          End Select
          
       Case Else
          ' Uhoh! Unhandled command key! Check for typo
          Debug.Assert False
          
       End Select
    End Sub

  17. #17

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    OK, I should have seen my last idea wasn't going to work because RegEx returns a collection, not a single item.

    Not a big deal but can't work the way I want it to probably.

    I'll post what I end up with.

  18. #18
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    Re: Need a way to parse tags that contain parameters

    Did you try the class/event approach? it will allow you to process a token for commands and execute them one at a time in series - because you get the TextBefore and TextAfter as parameter values you can print text as you see fit....if you ever need to stop part way through processing a token, set p_StopProcessing = True.

  19. #19
    Lively Member anycoder's Avatar
    Join Date
    Jan 2025
    Posts
    68

    Re: Need a way to parse tags that contain parameters

    I think it's easy to detect the possibe tag by simple InStr routine then you can validatd by Regexp or manually

    Code:
    Private Sub Command1_Click()
    Dim s As String, P1 As Long, P2 As Long, t As Long
    s = "Word before <PlaySound: BigGong> <PlaySound: TiresSquealing> word after."
    P2 = 1
    Do
      P1 = InStr(P2, s, "<")
      If P1 = 0 Then Exit Do
      t = InStr(P1 + 1, s, ">")
      If t = 0 Then Exit Do
      P1 = InStrRev(s, "<", t)
      Dim mTag As String
      mTag = Mid$(s, P1 + 1, t - P1 - 1)
      'here test tags validity
      If P2 < P1 Then
         Debug.Print "Txt:", Mid$(s, P2, P1 - P2)
      End If
      Debug.Print "Tag:", mTag
      P2 = t + 1
    Loop
    If P2 <= Len(s) Then
       Debug.Print "Txt:", Mid$(s, P2)
    End If
    
    End Sub
    The sample returns
    Code:
    Txt:          Word before 
    Tag:          PlaySound: BigGong
    Txt:           
    Tag:          PlaySound: TiresSquealing
    Txt:           word after.

  20. #20
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    Re: Need a way to parse tags that contain parameters

    You could even change it up so there is an event that fires for all the text before the command (so you can print it), then fires an event for the command and loops, finally firing a last event for the trailing text after all commands. That would allow you to easily sequence the printing and running of commands.

  21. #21

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    All of that is too much honestly.

    The engine processes only one line of text at a time (split by carriage returns) so sequencing the parameter scripts at exactly the right time isn't super important. The text will pop up immediately anyway, so even if I did that, it all happens in milliseconds and wouldn't be noticeable anyway. So I was trying to fix something that isn't even something that can be fixed. Also doesn't need to be.

    It's working well right now and I'm happy.

    It's a first draft so needs cleanup but here's the whole thing.

    The setup:

    Code:
    ' Declarations.
    
    Public Enum PARAMETER_TAG
    
      idx_ParameterTag_MakeBepes
      idx_ParameterTag_SeeSound
    
      ' More to come now that I have my fun new toy. :)
    
    End Enum
    
    Private Const MAX_PARAMETER_TAG As Long = idx_ParameterTag_SeeSound
    
    Private Sub PopulateParameterTags()
    Const STRING_PATTERN As String = "\s*(\w+)\s*>"
    
    ' sParameterTag must contain <.
    
    sParameterTag(idx_ParameterTag_SeeSound) = "<SeeSound:"
    sParameterPattern(idx_ParameterTag_SeeSound) = STRING_PATTERN
    
    sParameterTag(idx_ParameterTag_MakeBepes) = "<MakeBepes:"
    sParameterPattern(idx_ParameterTag_MakeBepes) = STRING_PATTERN ' Needs proper pattern to call MakeBepes. Now just testing to ensure the right things are happening.
    
    End Sub
    Raw text is sent here first:

    Code:
    Public Function ReplaceTokens(ByRef Text As String) As String
    Dim s As String
    Dim n As Long
    
    s = ProcessParameterTags(Text) ' This is the only new line of code in this procedure.
    
    For n = LBound(sToken) To UBound(sToken) ' This part already existed and processes tokens not having parameters. Nothing needs to be done here.
    
      s = FindTokens(s, sToken(n))
    
    Next n
    
    ReplaceTokens = s
    
    End Function

    ProcessParameterTags:

    Code:
    Private Function ProcessParameterTags(ByRef Token As String) As String
    Dim sParameter() As String
    Dim s As String
    Dim n As Long
    Dim j As Long
    
    ProcessParameterTags = Token
    
    If Not StringArrayInitialized(sParameterTag) Then Exit Function
    
    s = Token
    
    For n = LBound(sParameterTag) To UBound(sParameterTag)
    
      s = ProcessRegEx(s, sParameterTag(n), sParameterPattern(n), sParameter)
    
      If StringArrayInitialized(sParameter) Then
    
        For j = LBound(sParameter) To UBound(sParameter)
    
          Select Case n
    
            Case idx_ParameterTag_MakeBepes: MakeBepes idx_Sound_Default, 1, 100 ' This isn't hooked up yet. Needs the proper pattern. For now this is good for testing.
    
            Case idx_ParameterTag_SeeSound: SeeSound sParameter(j)
    
          End Select
    
        Next j
    
      End If
    
    Next n
    
    '  Stop
    
    ProcessParameterTags = s
    
    End Function

    ProcessRegEx:

    Code:
    Private Function ProcessRegEx(ByRef Token As String, ByRef Tag As String, ByRef RegExPattern As String, ByRef Parameter() As String) As String
    Dim m_RegEx As RegExp
    Dim colMatches As MatchCollection
    Dim m_Match As Match
    Dim sReturn As String
    
    ' Example: Send "Word before <PlaySound: BigGong> <PlaySound: TiresSquealing> word after."
    ' Return should be "Word before word after."
    
    sReturn = Token
    
    Erase Parameter
    
    Set m_RegEx = New RegExp
    
    With m_RegEx
    
      .IgnoreCase = True
      .Global = True
      .Pattern = Tag & RegExPattern ' "<SeeSound:\s*(\w+)\s*>"
    
      Set colMatches = .Execute(Token)
    
    End With
    
    For Each m_Match In colMatches
    
      ' m_Match.Value(1) = <SeeSound: BigGong>
      ' m_Match.Value(2) = <SeeSound: TiresSquealing>
    
      If Not StringArrayInitialized(Parameter) Then
    
        ReDim Parameter(0)
    
      Else
    
        ReDim Preserve Parameter(UBound(Parameter) + 1)
    
      End If
    
      Parameter(UBound(Parameter)) = GetTagParameter(Tag, m_Match.Value) ' Returns BigGong (first loop) and TiresSquealing (second loop).
    
      sReturn = StripTag(sReturn, Tag)
    
    Next
    
    ProcessRegEx = sReturn
    
    End Function

    GetTagParameter:

    Code:
    Private Function GetTagParameter(ByRef Tag As String, ByRef Value As String)
    Dim s As String
    
    s = Trim$(Replace(Value, Tag, vbNullString, 1, -1, vbTextCompare))
    
    s = StripBrackets(s)
    
    GetTagParameter = s
    
    End Function

    StripTag:

    Code:
    Private Function StripTag(ByRef Token As String, ByRef Tag As String) As String
    Dim nPos As Long
    Dim nEndPos As Long
    Dim s1 As String
    Dim s2 As String
    Dim n As Long
    
    StripTag = Token
    
    nPos = InStr(1, Token, Tag, vbTextCompare)
    
    If nPos = 0 Then Exit Function
    
    For n = nPos + 1 To Len(Token)
    
      If Mid$(Token, n, 1) = ">" Then
    
        nEndPos = n
    
        Exit For
      
      End If
    
    Next n
    
    If nEndPos = 0 Then Exit Function
    
    s1 = Left$(Token, nPos - 1)
    s1 = RTrim$(s1)
    
    s2 = Right$(Token, Len(Token) - nEndPos)
    s2 = LTrim$(s2)
    
    If s1 <> vbNullString And s2 <> vbNullString Then
    
      StripTag = s1 & " " & s2
    
    Else
    
      StripTag = s1 & s2
    
    End If
    
    End Function

  22. #22
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    Re: Need a way to parse tags that contain parameters

    Quote Originally Posted by cafeenman View Post
    All of that is too much honestly.
    Indeed, your approach is much more straight-forward!

  23. #23

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Need a way to parse tags that contain parameters

    I sense sarcasm.

    I really do appreciate the help.

    You know what this means, right? I can do anything I want!

    I am king of the world!

    I can run triggers and scripts and bears.

    oh my

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width