regular expression issue w/ TCL

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf regular expression issue w/ TCL

  • Creator
    Topic
  • #51658
    John Boyles
    Participant

      Ok – this one is starting to drive me nuts!

      I can not get certain regular expressions to evaluate properly in my TCL script.  I am trying to ensure that a variable starts with 12 numbers.

      echo [regexp {[^d{12}]} $obx14] <-- should eval to "true" if $obx14 starts wtih 12 numbers Have also tried these equivalent statements… ^dddddddddddd ^[0-9]{12} All should return true only if the string begins with 12 numbers.  I’ve tested all of these in other environments and they work properly.  However, all will incorrectly evaluate to “true” for empty strings or for strings of numbers < 12 in TCL.  See below: = true

      1 = true

      1a = false

      1111 = true

      a = false

      Any ideas?

    Viewing 21 reply threads
    • Author
      Replies
      • #71136
        Charlie Bursell
        Participant

          Close but no cigar  ðŸ˜€

          Just take it out of the brackets which means match anyone of the chars within the brackets.

          echo [regexp — {^d{12}} $obx14]

          Of course you could od something like:

          echo [regexp {[^d]{12}} $obx14]

          But why?

        • #71137

          The square brackets mean a range of characters or a set of characters like [0-9] or [a-b]. d is equivalent to [0-9].

          {^d{12}} is the same as {^[0-9]{12}.

          You can have more than one range in the square brackets like {[a-bA-B].}

          Here’s an example set: {[abc123]}. That would match on a, b, c, 1, 2, or 3.

          -- Max Drown (Infor)

        • #71138
          Alex Puzikov
          Participant

            I think that it should be this way

            regexp {^[d]{12}} $obx14

            carrot inside square brases states anything but 12 digits

            tcl>set obx14 12345678901a12

            12345678901a12

            tcl>regexp {^[d]{12}} $obx14

            0

            tcl>set obx14 a1234567890123

            a1234567890123

            tcl>!re

            regexp {^[d]{12}} $obx14

            0

            tcl>set obx14 1234567890123asc

            1234567890123asc

            tcl>!re

            regexp {^[d]{12}} $obx14

            1

            Regards,

            Alex

          • #71139
            John Boyles
            Participant

              Charlie,

              echo [regexp — {^d{12}} $obx14] works great!  

              Thanks much, guys!

            • #71140

              Alex Puzikov wrote:

              I think that it should be this way

              regexp {^[d]{12}} $obx14

              The square braces around the d are not needed. It would work, but not needed.

              -- Max Drown (Infor)

            • #71141
              Jennifer Hardesty
              Participant

                Instead of the 12 digit limitation, how would you do regexp {^d} $num where the num can end up being any digit greater than 0?

              • #71142

                regexp {^[1-9]} $obx14

                -- Max Drown (Infor)

              • #71143
                Jennifer Hardesty
                Participant

                  but that won’t take into account 10 or 100 or 1000.

                • #71144

                  Oh, I wouldn’t use regexp for that. Instead do something like “if {$var > 100}”. You can use regexp to capture the number if needed.

                  -- Max Drown (Infor)

                • #71145
                  Charlie Bursell
                  Participant

                    Or you could modify Max’s regexp like:

                    regexp {^[1-9]d*} $obx14

                    This will be true for any number that starts with 1-9 followed by 0 or more numbers after.  If the number following the 1-9 can only be 0, try:

                    regexp {^[1-9]0*} $obx14

                    Or as Max just said, if you are looking to see that a number larger than or 10 or 100, or whatever exists, simply do an if statement

                    You never did state the purpose of this.

                  • #71146
                    Jennifer Hardesty
                    Participant

                      Well I didn’t want to use if ($var > 0 ) because I am actually searching a file for a string that matches “150 Opening data connection for PATHTRNS (39123 bytes).” but where the filename, in this case “PATHTRNS”, and the file size can vary; however, if the file size is “0”, that’s an entirely different branch on my if/elseif/else statement.

                      I like [1-9]d*  —  it’s much simpler and easier to read than my [1-9][0-9]*?

                      Regexp seems like something very cool and “neat” like dating and politics until you actually try it and spend four days banging your head against a brick wall because you can’t figure out why it doesn’t work the way you think it should.

                    • #71147

                      What is the set of possible matches you are looking for? You have 150 in the example, but what could the other valid values be? What would an invalid value be?

                      -- Max Drown (Infor)

                    • #71148
                      Jennifer Hardesty
                      Participant

                        SUCCESSFUL FILE

                        150 Opening data connection for $fileName ($fileSize bytes).

                        EMPTY FILE

                        150 Opening data connection for $fileName (0 bytes).

                        MISSING FILE

                        550 $fileName: A file or directory in the path name does not exist.

                      • #71149

                        I’ve read your posts a couple of times, but I’m still not sure exactly what you need the regexp to do.

                        -- Max Drown (Infor)

                      • #71150
                        Jennifer Hardesty
                        Participant

                          O.K.

                          Our Cloverleaf server picks up and processes batch billing files for 5 or 6 applications/departments and the resulting charge files are placed in a folder called “BILLING”.  Currently, the mainframe-based finance application that does the actual billing picks up those files in the evening but it doesn’t delete them nor do we receive an email of any sort to indicate that the files have been successfully picked up by that application — when the “end users” don’t get their daily billing reports, the first people that are contacted are the billing people who insist they know nothing and the application folks always insist that everything worked on their side, which is why we currently have emails and daily reports which indicate what was successful and what wasn’t.  Of course, there is no way to prove that the billing application picked up the files or didn’t.

                          So, we finally convinced them to start sending us “something” which turns out to be one text file for each charge file which contains the ftp responses when the billing application attempted to grab the charge file.  Now, all I have to do is read that file into a list (each line is an element); then I have to step through that list and check for one of those three magic strings so I can then send an email and possibly multiple pages as needed.

                          Hopefully that explains better what I’m attempting to do.

                        • #71151

                          The magic strings are lines in the file? Can you paste the lines both valid and invalid?

                          -- Max Drown (Infor)

                        • #71152
                          Jennifer Hardesty
                          Participant

                            As above, a sample file would be:

                            Code:


                            EZA1736I FTP
                            EZY2640I Using /etc/ftp.data for local site configuration parameters.
                            EZA1450I IBM FTP CS V1R10
                            EZA1466I FTP: using TCPIP
                            EZA1456I Connect to ?
                            EZA1736I xxx.xx.xx.xx (EXIT
                            EZA1554I Connecting to:   xxx.xx.xx.xx port: 21.
                            220 bmc_p550_01 FTP server (Version 4.2 Fri May 2 12:48:10 CDT 2008) ready.
                            EZA1459I NAME (xxx.xx.xx.xx:TXDME):
                            EZA1701I >>> USER BILLING
                            331 Password required for BILLING.
                            EZA1701I >>> PASS
                            230-Last unsuccessful login: Tue Mar 24 07:07:47 EDT 2009 on ftp from xxx.xx.xx.xx
                            230-Last login: Wed Apr 14 20:00:13 EDT 2010 on ftp from ::ffff:xxx.xx.xx.xx
                            230 User BILLING logged in.
                            EZA1460I Command:
                            EZA1736I GET CARDTRNS   //DD:TRANSIN (REPLACE
                            EZA1701I >>> PORT xxx,xx,x,xx,xxx,xxx
                            200 PORT command successful.
                            EZA1701I >>> RETR CARDTRNS
                            550 CARDTRNS: A file or directory in the path name does not exist.
                            EZA1735I Std Return Code = 16550, Error Code = 00002
                            EZA1701I >>> QUIT
                            221 Goodbye.

                            I am looking for one of three possible lines — depending on the name of the file;  for example, in this case the name of this file would have told me to look for CARDTRNS as the file the ftp was attempting to pick up.  So $fileName = CARDTRNS.

                            Unfortunately, this script will not know the correct file size in bytes so this is my [1-9][0-9]*? because it can be any number greater than 0 if the file was successfully picked up.

                            SUCCESSFUL FILE

                            150 Opening data connection for $fileName ($fileSize bytes).

                            EMPTY FILE

                            150 Opening data connection for $fileName (0 bytes).

                            MISSING FILE

                            550 $fileName: A file or directory in the path name does not exist.

                          • #71153
                            David Barr
                            Participant

                              Are you trying to do something like this?

                              Code:

                              foreach line [split $filecontents n] {
                               if { [regexp {150 Opening data connection for (.*) (0 bytes).} $line -> filename] } {
                                 echo do something for empty file $filename
                               } elseif {[regexp {550 (.*): A file or directory in the path name does not exist.} $line -> filename] } {
                                 echo do something for bad transfer of $filename
                               } elseif { [regexp {150 Opening data connection for (.*) ((d+) bytes).} $line -> filename filesize] } {
                                 echo do something for good transfer of $filename with size $filesize
                               }
                              }

                            • #71154
                              Jennifer Hardesty
                              Participant

                                I had the hardest time with this.  For some reason I could not get {} around the regular expression to work.  I grep’d our tclproc dir and discovered that we have no examples of an if…regexp with braces around the regular expression.

                                The literal parenthesis () around the “0 bytes” was what was causing all of my problems apparently.  I finally figured out what I had to put there:

                                Code:


                                foreach line [split $msg “n”] {

                                # Check for No File Found
                                if {  [ regexp “^550 $billFile: A file or directory in the path name does not exist.$” $line ] }  {
                                                             #Process no File
                                                             break

                                # Check for empty file found —      
                                } elseif {  [ regexp “^150 Opening data connection for $billFile \((0 bytes\)).” $line ] }  {
                                                            #Process empty File
                                                             break

                                # If it’s not empty, it’s a Success!!!!
                                } elseif {  [ regexp “^150 Opening data connection for $billFile \(([1-9][0-9]*? bytes\)).” $line ] }  {
                                                            #Process successfully collected File
                                                             break
                                } else {
                                                            #do nothing

                                }

                                }

                                See this ridiculousness —

                                Code:

                                \(([1-9][0-9]*? bytes\)).

                                ?

                                The first two forward slashes make one literal slash “” so that the next parenthesis will be read as a literal parenthesis “(” by the regexp; the next parenthesis is actually the beginning of a grouping parenthesis apparently.   The confusing bits were the “\((” and “\))”.  It never occurred to me that the parenthesis were being read in that way.

                              • #71155
                                David Barr
                                Participant

                                  Normally it’s best to use squirrelies ({}) instead of quotes around regular expressions.

                                • #71156
                                  Charlie Bursell
                                  Participant

                                    Maybe I am missing something but it seems to me you rae making this overly complex.

                                    If there were an error fetching the file, I asume you will only have one line, the error message?  Why not simply put this code before the loop

                                    switch -regexp — $msg {

                                        ^550 {

                                                   Handle 550 error

                                         }

                                         

                                         ^150 {

                                                  if {[regexp — {0 bytes} $msg]]} {

                                                      Handle empty file

                                                  } else {

                                                     Handle error

                                                  }

                                          }

                                    }

                                    IF you get to here it is a good file then you can fo the loop

                                  • #71157
                                    Jennifer Hardesty
                                    Participant

                                      Well, part of the trick was to verify that it was in fact the correct file that was being picked up, which is why I had $billFile in the regexp.  To use your regexp, I would have to have a second regexp to verify that that the $billFile name is in that string/line after verifying that statement was in the file of ftp results codes.

                                      I wouldn’t want to assume that just because the file the Medipac script produces is called IMP_Results.txt that it really did pick up IMPCTRNS.  It’s better to check every little thing and make certain that our side is blunder-proof.

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