Regsub cmd to replace multiple occurances

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Regsub cmd to replace multiple occurances

  • Creator
    Topic
  • #48695
    Lawney Lovell
    Participant

      I am working on a script to cleanup .rtf message formatting and cannot figure out why this regsub statement is only replacing 1 occurance of the string when the condition exists multiple times.  I am trying to find the {xxxx } where xxxx can be anything and insert a space between xxxx and }.  This is a pain because the backslash and curly brace are part of the text but also affect the syntax for the regexp.

      Example:

      set text “DATE}{\fs24 }{\fs24 FIRST}{\fs24 }{\fs24 SEEN:}”

      echo $text

      regsub -all — {({B.*)(s})} $text {1 2} text

      echo $text

      Result:

      DATE}{fs24 }{fs24 FIRST}{fs24 }{fs24 SEEN:}

      DATE}{fs24 }{fs24 FIRST}{fs24  }{fs24 SEEN:}

      Any ideas would be helpful because I’ve tried every combination I can think of.

      Thanks!!

    Viewing 5 reply threads
    • Author
      Replies
      • #59417
        Jim Kosloskey
        Participant

          Lawney,

          Have you tried the string map function?

          It seems a lot clearer to me and rumor has it these string functions are highly optimized.

          Jim Kosloskey

          email: jim.kosloskey@jim-kosloskey.com 29+ years Cloverleaf, 59 years IT - old fart.

        • #59418
          Jamin Gray
          Participant

            One problem is that .* is greedy.  It will match the largest possible string that matches the pattern.

            What about this?

            Code:


            regsub -all {({\.{4} )(})} $text {1 2} text

            It captures a { follwed by a followed by 4 characters followed by a space.  then it captures the closing } and puts them together with a space between them.  

            Result:

            Code:


            hcitcl>regsub -all {({\.{4} )(})} $text {1 2} text2
            2
            hcitcl>puts $text
            DATE}{fs24 }{fs24 FIRST}{fs24 }{fs24 SEEN:}
            hcitcl>puts $text2
            DATE}{fs24  }{fs24 FIRST}{fs24  }{fs24 SEEN:}

          • #59419
            Mike Grieger
            Participant

              The ‘*’ being ‘greedy’ (as mentioned) is exactly what the issue is that you are having.  The way you have it written, it will only replace the LAST occurence in your test data, due to the greedy factor.

              adding the ? after the * makes the expression non-greedy, and works as you would want.

              (the letter ‘z’ is in there as it is easier to see than a space)

              set text “{DATE}{\fs24 }{\fs24 FIRST}{\fs24 }{\fs24 SEEN:}{\fs24 }{\fs24 }”

              echo $text

              regsub -all — {({B.*?)(s})} $text {1z2} text

              echo $text

              {DATE}{fs24 }{fs24 FIRST}{fs24 }{fs24 SEEN:}{fs24 }{fs24 }

              {DATE}{fs24z }{fs24 FIRST}{fs24z }{fs24 SEEN:}{fs24z }{fs24z }

            • #59420
              Lawney Lovell
              Participant

                Thank you Jamin.  This works but I can’t be sure that the formatting characters will always be 4 characters in length.  I will need to check 2, 3, 4, 5, 6, etc.  That is why I made it so generic.

              • #59421
                Lawney Lovell
                Participant

                  Mike, I used your code but modified slightly because I don’t want to insert an extra space after the formatting characters if it already exists.

                  So the expression captures a { follwed by a backslash followed by any number of non-space characters followed by a space.  Then it captures the closing } and puts them together with a space between them.

                  Example:

                  hcitcl>echo $text

                  DURATION}{fs24  }{fs24 OF}{fs24 }{fs24 SERVICE:}

                  hcitcl>regsub -all — {({BS*?s)(})} $text {1 2} text

                  1

                  hcitcl>echo $text

                  DURATION}{fs24  }{fs24 OF}{fs24  }{fs24 SERVICE:}

                  Thanks for the help!!

                • #59422
                  Anonymous
                  Participant

                    I may be simplifying this a bit much, but all you are wanting to do is place a space in front of the “}” unless a space is already there correct?

                    Example:  {TOM}{WAS }{HERE}

                    Should become:  {TOM }{WAS }{HERE }

                    Is this what you are wanting?  If so, then just have two regsubs.

                    The first:  regsub -all — ” }” $text “}” text

                    The second:  regsub -all — “}” $text ” }” text

                    This should give you what you want without having to worry about the backslashes…

                    Then again…I may be way off in understanding what you are looking for.

                Viewing 5 reply threads
                • The forum ‘Cloverleaf’ is closed to new topics and replies.