• Programming help - find specific numerics in strings

    From Arthur T.@21:1/5 to All on Sun Dec 23 02:15:48 2018
    I am using Regina, not ooRexx.

    I can program what I want to do (see below), but it seems
    inelegant and I wondered if any of you have better solutions.

    I have a string which is a filename. Before the final period
    there may be one or more numeric characters. I want to capture those
    numbers and their location.

    I'm pretty sure there will be exactly one period in the
    filename, but there might be non-contiguous numerics, which I'll have
    to ignore. There will definitely be filenames without these numerics
    which I'll have to bypass.

    Here is an overview of my proposed solution:

    1. REVERSE the string
    2. PARSE to split at the first period
    3. VERIFY to find the next non-numeric
    4. If non-zero, do the necessary arithmetic to find the location in
    the original string.

    --
    Arthur T. - ar23hur "at" pobox "dot" com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerard_Schildberger@21:1/5 to Arthur T. on Sun Dec 23 13:41:50 2018
    On Sunday, December 23, 2018 at 1:16:08 AM UTC-6, Arthur T. wrote:
    I am using Regina, not ooRexx.

    I can program what I want to do (see below), but it seems
    inelegant and I wondered if any of you have better solutions.

    I have a string which is a filename. Before the final period
    there may be one or more numeric characters. I want to capture those
    numbers and their location.

    I'm pretty sure there will be exactly one period in the
    filename, but there might be non-contiguous numerics, which I'll have
    to ignore. There will definitely be filenames without these numerics
    which I'll have to bypass.

    Here is an overview of my proposed solution:

    1. REVERSE the string
    2. PARSE to split at the first period
    3. VERIFY to find the next non-numeric
    4. If non-zero, do the necessary arithmetic to find the location in
    the original string.

    --
    Arthur T. - ar23hur "at" pobox "dot" com

    Here is a short REXX program that finds the 1st number (decimal digits only)
    in a character string, the search stops before the last period (if any) in a filename.

    The REXX code could be condensed, but I left the code to be be broken down
    so as to be easier to read and/or modify.


    /*REXX program finds decimal numerals in a filename before last period*/ /*------------------------ Only the first numerals (number) is found.*/
    parse arg fn /*fn could have embedded blanks.*/
    fn= strip(fn) /*strip leading/trailing blanks.*/
    if length(fn)==0 then do; say 'filename is empty.'; exit; end
    last.= lastpos(fn, .) /*get location of last period. */
    if last.==0 then last.= length(fn) /*has no period, use full name. */
    meat= left(fn, last. - 1) /*obtain a string where #'s are.*/
    # = 0123456789 /*numerals (decimal digits). */
    b = verify(meat, #, 'M') /*find beginning of a number. */
    if b==0 then do; say 'no number found.'; exit; end
    else say 'number starts at position' b
    e = verify(meat, #, , b) - 1 /*find number end.*/
    say 'number ends at position' e
    say
    say 'number is: ' substr(meat, b, e-b+1) ____________________________________________________ Gerard Schildberger

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arthur T.@21:1/5 to gerard46@rrt.net on Sun Dec 23 19:45:08 2018
    In
    Message-ID:<90d62cb2-d2c8-4588-a87d-ff74f09f6e21@googlegroups.com>, Gerard_Schildberger <gerard46@rrt.net> wrote:

    Here is a short REXX program that finds the 1st number (decimal digits only) >in a character string, the search stops before the last period (if any) in a >filename.

    Thank you. It's more general than I need because I'm looking for
    a number that starts immediately after the period (when reversed).
    But it's good to have working code to cannibalize so I can avoid some
    of the stupid mistakes.

    The REXX code could be condensed, but I left the code to be be broken down
    so as to be easier to read and/or modify.

    I tend not to condense my REXX code. Even when writing for
    myself, I follow Martin Golding's advice: "Always code as if the
    person who ends up maintaining your code will be a violent psychopath
    who knows where you live."


    --
    Arthur T. - ar23hur "at" pobox "dot" com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerard_Schildberger@21:1/5 to Arthur T. on Sun Dec 23 17:42:44 2018
    On Sunday, December 23, 2018 at 6:45:39 PM UTC-6, Arthur T. wrote:
    In
    Gerard_Schildberger wrote:

    Here is a short REXX program that finds the 1st number (decimal digits only) >in a character string, the search stops before the last period (if any) in a >filename.

    Thank you. It's more general than I need because I'm looking for
    a number that starts immediately after the period (when reversed).
    But it's good to have working code to cannibalize so I can avoid some
    of the stupid mistakes.

    The REXX code could be condensed, but I left the code to be be broken down >so as to be easier to read and/or modify.

    I tend not to condense my REXX code. Even when writing for
    myself, I follow Martin Golding's advice: "Always code as if the
    person who ends up maintaining your code will be a violent psychopath
    who knows where you live."


    --
    Arthur T. - ar23hur "at" pobox "dot" com

    Ah. My REXX program (shown previously) finds the first number in the
    filename (before the first period), while your code finds the last number.


    The modified REXX program to match what your algorithm does is (which has
    to contend with an "extra" error condition):

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ /*REXX program finds decimal numerals in a filename before last period*/ /*------------------------ Only the last numerals (number) is found. */
    parse arg fn /*fn could have embedded blanks.*/
    fn= strip(fn) /*strip leading/trailing blanks.*/
    if length(fn)==0 then do; say 'filename is empty.'; exit; end
    rev= reverse(fn) /*reverse the filename string. */
    dot= pos(., rev) /*find location of the period. */
    if dot==0 then say 'no period in the filename:' fn
    if dot==0 then dot= 1 /*test for special case: no dot*/
    b = verify(rev, 0123456789, 'M', dot) /*find beginning of a number. */
    if b==0 then do; say 'no number found.'; exit; end
    e = verify(rev, 0123456789, , b) - 1 /*find the "end" of the number. */
    if e<1 then e= length(rev) /*handle case of just a number. */
    num= reverse( substr(rev, b, e-b+1) ) /*extract the number, reverse it*/
    say 'number is: ' num @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    I normally use more whitespace, but this newsgroup reader condenses (er, butchers) whitespace. Comments are normally a bit further to the right. _____________________________________________ Gerard Schildberger

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arthur T.@21:1/5 to gerard46@rrt.net on Sun Dec 23 22:07:45 2018
    In
    Message-ID:<379e78db-630f-4f89-a5c1-6157418c203b@googlegroups.com>, Gerard_Schildberger <gerard46@rrt.net> wrote:

    Ah. My REXX program (shown previously) finds the first number in the >filename (before the first period), while your code finds the last number.


    The modified REXX program to match what your algorithm does is (which has
    to contend with an "extra" error condition):

    Thank you.

    e = verify(rev, 0123456789, , b) - 1 /*find the "end" of the number. */
    if e<1 then e= length(rev) /*handle case of just a number. */
    num= reverse( substr(rev, b, e-b+1) ) /*extract the number, reverse it*/

    Your "- 1" and "+1" fix exactly the kind of stupid error I might
    have made on my first tries. Sometimes I foresee the off-by-one
    errors; sometimes they come out in testing.

    --
    Arthur T. - ar23hur "at" pobox "dot" com

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)