Hi Bob, 

A) Since Andrew was the only one to respond so far, I'm adding my 0.2
cents. My solution differs from Andrew's:

1. In that it is much more bloated. Well, ok.

2. I try to more accurately model your specification (at least the way I
understand it). I believe Andrew didn't consider the prefix, suffix and
negation rules. Parsing and applying these rules introduces some additional
requirements that account for most of my code.

3. It could be reasonably argued that Andrew's version essentially
accomplishes the specification and that it is unreasonable to add quite a
few more lines of code in order to accomplish a small number of additional
subtleties. But I wanted to show that REBOL is up to the challenge.

B) A few notes:
1. If the rules you provide are not met, I return false! I.e. searchlist
must contain either a leading "^", a trailing "$", or both, but must
contain at least one. A list that contains neither a suffix nor a prefix
indicator automatically leads to rejection.

2. you wrote:
>and () are used in the app being ported.

I interpret "and" here to be part of your explanatory text and not a
keyword used by the app.

3. Your use of a single caret character "^" is not accepted by REBOL (as
Andrew pointed out), because it is REBOL's string escape character. I
therefore replaced it by two caret characters, "^^", where the first caret
escapes the second caret, thereby restoring it as a simple character with
no special functionality.

4. You don't specify suffix and prefix. I assume that they separated by a
dot character ".".

5. You don't specify whether the front and end anchors ("^" and "$"
respectively) must appear at the beginning (or end) of the string. Neither
do you mention whether not ("?!") must appear at the beginning of the
string. I assume that your example indicates that this is an implied rule.

6. My code may be a little overly verbose. I wanted it to be instructive.
Besides that, I also wanted to ensure that all your requirements are met.
If you set the word verbose to true, you will get a verbos console print out. 


C) The Implementation

you wrote:
>>>source is-memberof-re
>?

REBOL []

verbose: false
vprint: func [string] [
  if verbose [print string]
]
reset: func [] [
  front-anchor: end-anchor: use-negate: false
]

front-anchor-rule: [thru "^^(" mark: 
  (vprint "found front-anchor" front-anchor: true)
]
negate-rule:    [thru "?!(" mark: 
  (vprint "in negate-rule" use-negate: true)
]
end-anchor-rule: [thru ")$" end: 
  (vprint "found end-anchor" end-anchor: true)
]
close-paren-rule: [to ")" end: skip ]

parse-rule: [(reset) 
  some [front-anchor-rule | negate-rule] 
  end-anchor-rule some close-paren-rule to end
]


is-memberof-re: func [ condition [string!] candidate [string!] 
                       /local position end condition-block check-block match 
                     ] [
  mark: 1
  end: length? condition  
  parse :condition parse-rule
  if series? mark [mark: index? mark]
  end: end - mark - 1
  condition-block: parse copy/part at condition mark end "|"
  vprint mold condition-block
  either all [front-anchor end-anchor] [
    match: candidate
  ][
    either not all [front-anchor end-anchor] [
      return false
    ] [
      if (length? parse candidate ".") = 1 [return false]
      match: do either front-anchor [ :first ] [ :second ] parse candidate "."
    ]
  ]
  check-block: foreach option condition-block [append [] (= match option)]
  vprint mold check-block
  either use-negate [ 
    return not all check-block 
  ] [
    return any check-block
  ]
]                     

;- note that I've added a caret "^^":
userlist:  {^^(ted|admin|bobr|andrew|elan|keith|cheryl|joel|brady)$}
current-user: "bobr"
excluded-files: {^^(?!(notxt|ask_new|only_owner_may_edit))}


print [
  "is-memberof-re userlist current-user:" 
  is-memberof-re userlist current-user
]

print [
  "is-memberof-re excluded-files myfavoritemartian.html:" 
  is-memberof-re excluded-files "myfavoritemartian.html"
]

;- end script
Sample run:

>> do %bob-match.r
Script: "Untitled" (none)
is-memberof-re userlist current-user: true
is-memberof-re excluded-files myfavoritemartian.html: false

>>


>how do I look in a string to see it matches
>a simple regular expression
>where the regular expression
>is coming from buffers/inputs and not part of the compiled script?
>by simple I mean that only 
>^ (front anchor - missing front tests for suffixes)
>$ (end anchor - missing end tests for prefixes)
>| (alternates)
>?! (not)
>and () are used in the app being ported.
>
>
>sample initial conditions:
>
>userlist:  {^(ted|admin|bobr|andrew|elan|keith|cheryl|joel|brady)$}
>current-user: "bobr"
>excluded-files: {^(?!(notxt|ask_new|only_owner_may_edit))}
>
>
>is-memberof-re userlist current-user
>>> true
>
>is-memberof-re excluded-files "myfavoritemartian.html"
>>> false
>
>
>


;- Elan >> [: - )]

Reply via email to