[plt-scheme] Small problem with regex-replace*
From: Jaime Vargas (jev at mac.com)
Date: Fri Jun 16 12:14:45 EDT 2006 |
|
Danny thanks for the help I didn't read the manual, my bad. And you were right about that the scrambler fails for short strings. Here is the corrected version.
(require (lib "cards.ss" "games" "cards"))
(define (shuffle-string str)
(list->string (shuffle-list (string->list str) 2)))
(define (scramble str)
(define len (string-length str))
(if (<= len 3)
str
(let ([len-1 (sub1 len)])
(string-append
(substring str 0 1) ; First char
(shuffle-string (substring str 1 len-1)) ; Shuffle mid-part
(substring str len-1 len))))) ; Last char
(define (scramble-text str)
(let ([word (regexp "[a-zA-Z]+")])
(regexp-replace* word str scramble)))
(scramble-text "In theory after scrambling this text would be still readable.")
On Thursday, June 15, 2006, at 11:09PM, Danny Yoo <dyoo at hkn.eecs.berkeley.edu> wrote:
>> I was happy this was a very small program to write, however I wasn't able to
>> create a regexp that only match words,
>> so I ended using *dummy* variable to hold the second match that is passed to
>> the scramble procedure. How can I fix this?
>
>
>Hi Jaime,
>
>The issue is that the regular expression has a group, which we define by
>putting parens in the regexp pattern:
>
> (let ([word (regexp "([a-zA-Z])+")]) ...)
>
>Here, any matches on our regexp will return two results: one for the whole
>match, and the others for each group in the pattern.
>
>What you probably want is:
>
> [a-zA-Z]+
>
>which doesn't define a group, so it'll give us a single reported match.
>
>
>Alternatively, we can look at the documentation on regex patterns:
>
>http://pre.plt-scheme.org/docs/html/mzscheme/mzscheme-Z-H-10.html#node_chap_10
>
>and see the following snippet:
>
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>Atom ::= (Regexp) Match sub-expression Regexp and
> report match
> | (?:Regexp) Match sub-expression Regexp
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
>
>So there's a way of defining a sub-expression regex without causing match
>to report it.
>
>
>Let's play with regexp-match just to make this concrete:
>
>;;;;;;
>> (regexp-match "[a-zA-Z]+" "hello world")
>("hello")
>> (regexp-match "([a-zA-Z]+)" "hello world")
>("hello" "hello")
>> (regexp-match "([a-zA-Z])+" "hello world")
>("hello" "o")
>> (regexp-match "(?:[a-zA-Z]+)" "hello world")
>("hello")
>;;;;;;
>
>(The result for "([a-zA-Z])+" surprises me!)
>
>
>Finaly, the scrambling code might need some clarification. What happens
>on words with only one letter in them?
>
>
>Best of wishes to you!
>
>