tags:

views:

34

answers:

2

I tried to colorize in rebol an url like this

content: "http://domain.com/test.php?keyword=hdhdf&hdhd=sdcfsv&sbcfsv=sdncfd&sncfsdv=dncsv&cnsv=dshdkd&scsv=12334&DXV=D&SWJDJJDFDJQKKKKKKKKKKKK&DFG=V&DJJF=DJVNVV&DJFFFFFFFFFF=33333"

rule-keyword-0: [to "?" thru "?" mark: (insert mark {<font color="red">}) 19 skip to "=" mark: (insert mark "</font>") thru "="]
rule-keyword-1: [to "&" thru "&" mark: (insert mark {<font color="red">}) 19 skip to "=" mark: (insert mark "</font>") thru "="] 

rule-value-0: [to "</font>=" thru "</font>=" mark: (insert mark {<font color="blue">}) 20 skip to "&" mark: (insert mark "</font>") thru "&"]
rule-value-1: [to "</font>=" thru "</font>=" mark: (insert mark {<font color="blue">}) 20 skip to end mark: (insert mark "</font>")] 

rule-keyword: [any [rule-keyword-0 | rule-keyword-1] to end]
rule-value: [any [rule-value-0 | rule-value-1] to end]

parse content rule-keyword
parse content rule-value

But output is not right (see for example double font color="blue" at the end):

http://domain.com/test.php?&lt;font color="red">keyword</font>=<font color="blue">hdhdf</font>&<font color="red">hdhd</font>=<font color="blue">sdcfsv</font>&<font color="red">sbcfsv</font>=<font color="blue">sdncfd</font>&<font color="red">sncfsdv</font>=<font color="blue">dncsv</font>&<font color="red">cnsv</font>=<font color="blue">dshdkd</font>&<font color="red">scsv</font>=<font color="blue">12334</font>&<font color="red">DXV</font>=<font color="blue">D&<font color="red">SWJDJJDFDJQKKKKKKKKKKKK</font>&DFG</font>=<font color="blue">V&<font color="red">DJJF</font>=DJVNVV</font>&<font color="red">DJFFFFFFFFFF</font>=<font color="blue"><font color="blue">33333</font>

What the correct rule

A: 

You didn't specify what the correct output would look like, and so submitting incorrect code and asking us to guess what you were trying to do is a bit much! I will, as usual, suggest reducing your example to the smallest possible that reproduces your problem. (That will often lead you to the solution before you have to ask the question!)

http://catb.org/esr/faqs/smart-questions.html#code

But off the cuff, I suspect you are experiencing the fact that any code in parentheses is executed during the rule match, whether the rule winds up matching or not. Look at this simple example:

>> rule-1: ["a" (print "a matched in rule-1") "b"]
== ["a" (print "a matched in rule-1") "b"]

>> rule-2: ["a" (print "a matched in rule-2") "c"]
== ["a" (print "a matched in rule-2") "c"]

>> parse "ac" [any [rule-1 | rule-2]]
a matched in rule-1
a matched in rule-2
== true

Though the first rule failed, you get both printouts! The printout from rule-1 happened because the code in parentheses executed before the failure had been determined.

Your "any" running two rules that may or may not match, both doing insertions before figuring out the full match, looks like your problem.

Hostile Fork
Sorry HostileFork, I couldn't make simple example because when it's simple it did work :) As for the result I wanted this was in the question.
Rebol Tutorial
+1  A: 

There are probably more elegant rules but this seems to work for your data, assuming that I have guessed what you want.

   content: "http://domain.com/test.php?keyword=hdhdf&amp;hdhd=sdcfsv&amp;sbcfsv=sdncfd&amp;sncfsdv=dncsv&amp;cnsv=dshdkd&amp;scsv=12334&amp;DXV=D&amp;SWJDJJDFDJQKKKKKKKKKKKK&amp;DFG=V&amp;DJJF=DJVNVV&amp;DJFFFFFFFFFF=33333"


    result: parse content [
        thru "?"
        some [
            ; we should be at the beginning of the pairs
            mark1: 
            copy stuff to "=" mark2: (
                ; to ensure that there is a pair here
                if stuff [
                    insert mark2 </font>
                    insert mark1 <font color="red">
                ]
            )
            ; find the = sign
            thru </font> thru #"="
            mark1:
            [ copy stuff to #"&" | copy stuff to end ]
            mark2: 
            (   if stuff [
                    insert mark2 </font> 
                    insert mark1 <font color="blue">
                ]
            )   
            thru </font>
            [ thru "&" | end ]  
        ]
    ]

    ?? result
    ?? content
Graham Chiu
I looked at the result: that gives what I wanted thanks. Now I will be scratching my head to understand your code. Sometimes parse seems hard for simple requirements :) Maybe in that kind of case regex is simpler ?
Rebol Tutorial
What I always try to do is some composition rule for parse rules (start with 2 independant rules and aggregate them) but that doesn't seem possible or difficult with parse.
Rebol Tutorial
All it does is find the pairs around the =, marks the spot where each string is to be inserted, then inserts the 2nd one first ( if I inserted the first one first, then the position of the second one will be altered ), and then the 1st one second. I then skip past the stuff I inserted. After the blue font, I then check to see if I'm at the end.You could do this with several rules as well but I just did it in one.
Graham Chiu