'''Problem Statement: ''' [CJB]: To validate a string as a variety of integer types (binary, octal, decimal, hexadecimal) excluding 0nnn octals. Also uses upvar to return the valid types for the given string, and strips left padded 0's for strings without a type modifier (0x|0b|0o). '''Code: ''' ====== #Figures out if a string could be a variety of integers, and then compares a given type to the list of types. #Ignores 0nnn octal numbers. #Will upvar a non-0nnn octal number to 'num_var' (strips extra 0's) #Will upvar the valid types for this string into 'types_var' #Returns 1 if the given type is a valid type for this string, else returns 0 proc regex_validate {string {type hexadecimal} {num_var ""} {types_var ""}} { if {$types_var ne ""} { upvar $types_var types } set types [list hexadecimal decimal octal binary none] regexp -nocase -all -line -- {(^[-+]|^)(0x|0b|0o|)(0*)([01]*)([0-7]*)([0-9]*)([0-9a-f]*)(\w*)} $string match sgn mod pad0 bin oct dec hex str #Eliminate invalid types if {$str ne ""} { set types [list] } elseif {$hex ne ""} { set types [lrange $types 0 0] } elseif {$dec ne ""} { set types [lrange $types 0 1] } elseif {$oct ne ""} { set types [lrange $types 0 2] } elseif {$bin ne ""} { set types [lrange $types 0 3] } else { set types [lrange $types 0 4] } #Modifier check and elimination switch -nocase -- $mod { 0x {set types [lsearch -inline $types hexadecimal]} 0o {set types [lsearch -inline $types octal]} 0b {set types [lsearch -inline $types binary]} } #Return number via upvar if needed. Removes left padded 0's for numbers without a modifier if {$num_var ne ""} { upvar $num_var num if {$mod eq ""} { set num ${sgn}${bin}${oct}${dec}${hex}${str} } else { set num $match } } return [expr {[lsearch $types $type] >= 0}] } #Alternate prototype using [scan] instead of [regexp] proc scan_validate {string} { scan $string %x%s hex s if {![info exists s]} { scan $string %d%s dec s if {![info exists s]} { scan $string %o%s oct s if {![info exists s]} { #binary check? return hex|dec|oct } else { return hex|dec } } else { return hex } } else { return NaN } } ====== '''Discussion: ''' [CJB]: I put this here instead of in [Advanced Regular Expression Examples] due to being more than a few lines like the examples found there. See also: * [re_syntax] * [regexp] * [Regular Expression Examples] * [Advanced Regular Expression Examples] ---- !!!!!! %| [Category String Processing] |% !!!!!!