wildcard matching in rexx
Posted: Mon Sep 05, 2016 5:05 am
the * matches 0 or more chars
the ? matches 1 char
quick and dirty,
it compiles the pattern, and then executes the result
the ? matches 1 char
Code: Select all
#! /usr/bin/env rexx
Trace "O"
signal on novalue name novalue
signal on halt name halt
signal on syntax name syntax
numeric digits 8
Pattern = 'A?C*D??E*'
String = 'ABCxxDyyEzz'
Say "match( '"String"', '"Pattern"') =>" match( String, Pattern)
Pattern = 'A?C*D??E*'
String = 'ABCxxDyyyEzz'
Say "match( '"String"', '"Pattern"') =>" match( String, Pattern)
Pattern = 'A?C*D??E*'
String = 'ABCxxDyyEzz'
stages = compile(pattern)
Say "fastmatch( '"String"', '"stages"') =>" fastmatch( String, stages)
Pattern = 'A?C*D??E*'
String = 'ABCxxDyyyEzz'
stages = compile(pattern)
Say "fastmatch( '"String"', '"stages"') =>" fastmatch( String, stages)
exit
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
match:procedure
-- trace "I"
parse arg string, pattern, ?char, ?wild, ?escape
if ?char = "" then ,
?char = "?"
if ?wild = "" then ,
?wild = "*"
if ?escape = "" then ,
?escape = "\"
stages = compile(pattern, ?char, ?wild, ?escape)
string = string || "ff"x
strlen = length(string)
index = 1
do while ( stages \= "" )
parse var stages func parm stages
interpret "index = "func"('"string"','"strlen"','"parm"','"index"')"
-- Trace "O"
if index = (-1) then ,
return 0
end
return 1
return 0
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
fastmatch:procedure
-- trace "I"
parse arg string, stages
string = string || "ff"x
strlen = length(string)
index = 1
do while ( stages \= "" )
parse var stages func parm stages
interpret "index = "func"('"string"','"strlen"','"parm"','"index"')"
if index = (-1) then ,
return 0
end
return 1
return 0
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
chklen:
-- Trace "I"
parse arg ?string, . , ?strlen, .
if length(?string) < ?strlen then ,
return (-1)
return 1
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
compare :
-- Trace "I"
parse arg ?string, ?strlen, ?needle, ?index
if ?index + length(?needle) - 1 > ?strlen then ,
return (-1)
if substr(?string, ?index, length(?needle)) = ?needle then ,
return ?index + length(?needle)
return (-1)
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
advance:
-- Trace "I"
parse arg ?string, ?strlen, ?count, ?index,
if ?index + ?count - 1 <= ?strlen then ,
return ?index + ?count
return (-1)
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
locate:
-- Trace "I"
parse arg ?string, ?strlen, ?needle, ?index
if ?index + length(?needle) - 1 > ?strlen then ,
return (-1)
?chindx = pos(?needle, ?string, ?index)
if ?chindx >= ?index then ,
return ?chindx + length(?needle)
return (-1)
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
compile:procedure
-- trace "I"
parse arg pattern, ?char, ?wild, ?escape
if ?char = "" then ,
?char = "?"
if ?wild = "" then ,
?wild = "*"
if ?escape = "" then ,
?escape = "\"
pattern = pattern || "ff"x
strlen = 0
stages = ""
escape = 0
dofind = 0
doskip = 0
token = ""
index = 1
do while ( index <= length(pattern) )
ch = substr(pattern, index, 1)
if escape then do
escape = 0
strlen += 1
if doskip > 0 then do
stages = stages "advance" doskip
doskip = 0
end
if dofind > 0 then do
stages = stages "locate" token
dofind = 0
iterate
end
token = token || ch
index +=1
iterate
end
if ch = ?escape then do
escape = 1
index += 1
iterate
end
select
when ( ch = ?wild ) then do
if token \= "" then do
stages = stages "compare " token
token = ""
end
dofind += 1
end
when ( ch = ?char) then do
strlen += 1
if token \= "" then do
stages = stages "compare " token
token = ""
end
doskip += 1
end
otherwise do
strlen += 1
if doskip > 0 then do
stages = stages "advance" doskip
doskip = 0
end
if dofind > 0 then do
stages = stages "locate" ch
dofind = 0
index +=1
iterate
end
token = token || ch
end
end
index += 1
end
if index \= length(pattern) + 1 then ,
return -1
if token \= "" then ,
stages = stages "compare " token
stages = "chklen" strlen stages
return space(stages)
return (-1)
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
logic_error:
say "** "copies("- ",35)
say "** Logic error at line '"sigl"' "
say "** "
exit
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
syntax:
say "** "copies("- ",35)
say "** ON syntax trapped, line '"sigl"' var '"condition("D")"' "
say "** "
exit
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
novalue:
say "** "copies("- ",35)
say "** ON novalue trapped, line '"sigl"' var '"condition("D")"' "
say "** "
exit
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
halt
say "** "copies("- ",35)
say "** ON halt trapped, line '"sigl"' var '"condition("D")"' "
say "** "
exit
it compiles the pattern, and then executes the result