regular expression issue w/ TCL

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

Forum Statistics

Registered Users
5,117
Forums
28
Topics
9,292
Replies
34,435
Topic Tags
286
Empty Topic Tags
10