PDA

View Full Version : Checking a position for a Range (A toZ , 0 to 9)



Guest.Visitor
01-14-2002, 10:44 AM
There's no syntax in the language to specify a range of characters (like you can code in regular expressions in some modern languages). You can try the %CHECK (Check Characters) (http://publib.boulder.ibm.com/pubs/html/as400/v5r1/ic2924/books/c0925083548.htm#HDRBBCHK) built-in function to see if a field contains any of a set of characters.

B.Morris
01-14-2002, 12:24 PM
>There's no syntax in the language to specify a range of characters (like >you can code in regular expressions in some modern languages). You should be able to call the C-runtime regular-expression functions from RPG. (See regex.h). I've never had any success doing so, but I haven't tried very hard. Maybe I'll revisit my program and try again. I think it would probably be overkill in this case, since a few CHECKs will do the trick.

Guest.Visitor
01-14-2002, 12:45 PM
I think the following will work in your example: C if Licno1 < 'A' OR Licno1 > 'Z' OR C Licno2 < 'A' OR Licno2 > 'Z' OR C LICNO35 < '0'

Guest.Visitor
01-15-2002, 05:54 AM
Checking that a character is between 'A' and 'Z' may well work in an ASCII environment since 'A'-'Z' are contiguous in ASCII. But they are not contiguous in EBCDIC. In particular, characters, X'CA'-X'D0' and X'DA'-X'E1' are between 'A' (X'C1') and 'Z' (X'E9'), but they are not alphabetic characters. For example, characters '}' and '' fall into this range. (At least the digits '0'-'9' are continguous in both ASCII and EBCDIC.)

Guest.Visitor
01-15-2002, 06:04 AM
Of course you're dead right, Hans. This has not been a good year. I think I should go back into hibernation for a few more weeks.

B.Morris
01-15-2002, 12:51 PM
Barbara Morris wrote: > > You should be able to call the C-runtime regular-expression functions > from RPG. (See regex.h). > > I've never had any success doing so, but I haven't tried very hard. > Maybe I'll revisit my program and try again. I found my old code and my problem. Good old "copy and fix up" failed me again. To save typing 3 or 4 characters, I copied a prototype, changed the name, but forgot to change the EXTPROC parameter, so I was calling the wrong function. For what it's worth, here's a little program that calls the regular-expression functions. I wrote it just for playing, so it takes 2 parameters up to 32 bytes: a regular expression and a string. It then displays any error messages or the "found" sections in the string. (I _really_ don't recommend this for dbcumbie's current problem - major overkill, I think, not even counting any learning about regular expressions.) Tip: if anyone tries this and copies RE examples from say a C manual, watch out for strings with doubled back-slashes. In C, \ in a string just means a single slash. Sort of like RPG's doubled apostrophe. Try ===> CALL WHATEVER ('[0-9][a-z]*[0-9]' '3abc2') (finds 3abc2) ===> CALL WHATEVER ('[0-9][a-z]*[0-9]' '3abc2xxx') (finds 3abc2) ===> CALL WHATEVER ('[0-9][a-z]*[0-9]' '3abcx') (no match) H dftactgrp(*no) bnddir('QC2LE') * See QSYSINC/H(REGEX) D ds based(typedefDummyPointer) D size_t 10u 0 D mbstate_t 5i 0 D LC_colval_t 10i 0 D off_t 10i 0 /* regcomp() cflags - add together for more than one */ D REG_BASIC c x'00' D REG_EXTENDED c x'01' D REG_ICASE c x'02' D REG_NEWLINE c x'04' D REG_NOSUB c x'08' /* regexec() eflags - add together for more than one */ D REG_NOTBOL c x'0100' D REG_NOTEOL c x'0200' /* Regular Expression error codes */ D REG_NOMATCH c 1 D REG_BADPAT c 2 D REG_ECOLLATE c 3 D REG_ECTYPE c 4 D REG_EESCAPE c 5 D REG_ESUBREG c 6 D REG_EBRACK c 7 D REG_EPAREN c 8 D REG_EBRACE c 9 D REG_BADBR c 10 D REG_ERANGE c 11 D REG_ESPACE c 12 D REG_BADRPT c 13 D REG_ECHAR c 14 D REG_EBOL c 15 D REG_EEOL c 16 D REG_ECOMP c 17 D REG_EEXEC c 18 D REG_LAST c 18 D regex_t DS ALIGN D re_nsub LIKE(size_t) D re_comp * D re_cflags 10i 0 D re_erroff LIKE(size_t) D re_len LIKE(size_t) D re_ucoll LIKE(LC_colval_t) DIM(2) D re_lsub * D reserved1 * DIM(9) D re_esub * D re_specchar * D re_phdl * D reserved2 * DIM(7) D re_map 256A D re_shift LIKE(mbstate_t) D re_dbcs 5i 0 D regmatch_t DS D matches DIM(10) D rm_so LIKE(off_t) D OVERLAY(matches : *next) D rm_ss LIKE(mbstate_t) D OVERLAY(matches : *next) D pad1 2a OVERLAY(matches : *next) D rm_eo LIKE(off_t) D OVERLAY(matches : *next) D rm_es LIKE(mbstate_t) D OVERLAY(matches : *next) D pad2 2a OVERLAY(matches : *next) * prototypes D regexec pr 10i 0 extproc('regexec') D regex LIKE(regex_t) const D string * value options(*string) D numRegmatch value LIKE(size_t) D regmatch LIKE(matches) dim(10) D options(*varsize) D eflags 10i 0 value D regcomp pr 10i 0 extproc('regcomp') D regex LIKE(regex_t) D string * value options(*string) D cflags 10i 0 value D regerror pr 10i 0 extproc('regerror') D errCode 10i 0 value D regex LIKE(regex_t) const D string * value D len LIKE(size_t) value D regfree pr extproc('regfree') D regex LIKE(regex_t) D rc s 10i 0 D i s 10i 0 D msg s 52a D startPos s 10i 0 D len s 10i 0 D error pr D errCode 10i 0 value D regex LIKE(regex_t) C *entry plist C parm pattern 32 C parm string 32 C eval rc = regcomp (regex_t: %trim(pattern): 0) C if rc <> 0 C callp error (rc : regex_t) C return C endif C eval rc = regexec (regex_t C : %trim(string) C : %elem(matches) C : matches C : 0) C if rc <> 0 C callp error (rc : regex_t) C return C endif C for i = 1 to %elem(matches) C if rm_so(i) < 0 C leave C endif C eval startPos = rm_so(i) + 1 C eval len = rm_eo(i) - rm_so(i) C eval msg = %char(i) + ': ' C + %subst(string : startPos : len) C msg dsply C endfor C callp regfree (regex_t) C return P error b D error pi D errCode 10i 0 value D regex LIKE(regex_t) D errbuf s 52a C callp regerror (rc : regex_t C : %addr(errbuf) : %size(errbuf)) C errbuf dsply C callp regfree (regex_t) P error e

Guest.Visitor
01-15-2002, 02:13 PM
You can use C-runtime function isupper to test if a character is an uppercase letter, and isdigit to test if it is a decimal digit.

trevor.lazarus@ssa.gov
01-16-2002, 10:04 AM
Barbara, the code works for me. But I can't decipher it. Where are these functions documented? I looked in the c library, and infocenter (which isn't) and qsysinc/h .... Trevor

Guest.Visitor
01-16-2002, 11:01 AM
regcomp (http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/qb3at500/1.2.132) compiles a regular expression; regexec (http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/qb3at500/1.2.134) executes the compiled regex.

trevor.lazarus@ssa.gov
01-16-2002, 11:45 AM
Thank-you. I was looking in the wrong book. http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QBJATN00/ccontents Trevor

B.Morris
01-17-2002, 07:47 AM
Nick already gave the links for the functions, but they don't really talk at all about what regular expressions are, or how to code them. If you need to learn about regular expressions, here's a regular expression tutorial: http://www.javaregex.com/pat/tutorial/tutorial.html (it assumes you're using Java, but it still applies, as long as you remember that you don't have to double your \s they way it shows). Something I found out yesterday: if you don't use extended mode, parentheses () are ordinary characters, and you have to escape them ( and ) to get them to behave as regular expression special characters. But in extended mode, it's the other way around.

Guest.Visitor
01-17-2002, 08:20 AM
It should be noted that the regular expression functions appear to follow the ASCII collating sequence on OS/400, not EBCDIC. Thus, ranges such as [A-Z] will work as expected. (That is, [A-Z] is treated as a contiguous unbroken sequence of uppercase letters.)

Guest.Visitor
01-17-2002, 11:54 AM
You forgot to explain why there is a gap at 'E1'X. bobh

Guest.Visitor
01-17-2002, 01:14 PM
Hans didn't explain ANY of the gaps in the EBCDIC sequence! I've heard the gaps are a legacy of EBCDIC (http://www.cwi.nl/~dik/english/codes/stand.html#ebcdic)'s evolution from punched cards. Why the gap is at E1 rather than E9 or C1 or D1, I don't know!

Guest.Visitor
01-18-2002, 05:07 AM
The alpha coding on Hollerith cards is double-punching, using the 12 row for A-I, the 11 row for J-R, and the (10 or 0) row for S-Z. This was carried over into the hex C D and E zones. The coding for S was made 0-2 rather than 0-1 because, as I understand it, the card readers might have a problem in interpreting two punches in adjacent rows This then offset all letters after R by one. Bill

Guest.Visitor
01-18-2002, 05:10 AM
Is there a way for me to code the following in RPG, I need to check certain positions of a field for a range of characters from A to Z, A to F, etc. If Licno1 Not Equal 'A' thru 'Z' or Licno2 Not Equal 'A' thru 'Z' or Licno35 Not Numeric Eval Msg = 'Incorrect Forest TAG#' Print error-report Endif

Guest.Visitor
01-18-2002, 05:10 AM
You can search the web for details on EBCDIC's history. The Jargon Dictionary has a good description of EBCDIC (http://info.astrian.net/jargon/terms/e/EBCDIC.html). (This is one of the kinder discussion of EBCDIC on the net!) Regarding regular expressions (discussed earlier in this forum), it should be noted that one of the more commonly used characters in RE's is '^' (AKA, caret). If you want to use RE's in your iSeries apps, you might need to play around with the keyboard mappings on your 5250 terminal emulator.