Working with variables – to, thru, and copy

The exchange rates file was named rates.xml, and when we look at its contents in an editor, it consists of a number of <item> XML tags, each containing an exchange rate, such as this:

<item>
<title>1 USD = 0.81191502 EUR</title>
<link>http://www.floatrates.com/usd/eur/</link>
<description>1 U.S. Dollar = 0.81191502 Euro</description>
<pubDate>Fri, 23 Mar 2018 00:00:01 GMT</pubDate>
<baseCurrency>USD</baseCurrency>
<baseName>U.S. Dollar</baseName>
<targetCurrency>EUR</targetCurrency>
<targetName>Euro</targetName>
<exchangeRate>0.81191502</exchangeRate>
</item>
<item>
<title>1 USD = 0.70675954 GBP</title>
...
</item>

We see that this contains all the information we need; in fact, only <title> is enough.

Let's see how we could parse that string: 

 rate: "<title>1 USD = 0.81191502 EUR</title>"

To move the parse position pointer just before a string str, you use the to rule—to str.

We can show this by inserting a variable pos, which represents the rest of the series at that point (don't forget the :).  The position in the series is then given by index? pos:

;-- see Chapter08/searching-and-changing.red:
parse rate [to "<title>" pos:] ;== false
pos ;== "<title>1 USD = 0.81191502 EUR</title>"
index? pos ;== 1

To move the parse position pointer just after the string str, you use the thru rule—thru str.

If we apply this to rate, we get the following:

parse rate [thru "<title>" pos:]   ;== false
pos ;== "1 USD = 0.81191502 EUR</title>"
index? pos ;== 8

In our case, the exchange rate information we want is inside the <title> tag. So we want to parse just after "<title>", until just before "</title>".

Let's try the following:

parse rate [thru "<title>" to "</title>"]

But this gives false, because we didn't parse to the end of the input. To go all the way through to the end making parse return true, use the dedicated end word:

parse rate [thru "<title>" to "</title>" to end]

Combining thru and to, we can also get the positions:

parse rate [thru "<title>" pos1: to "</title>" pos2: to end] ;== true
pos1 ;== "1 USD = 0.81191502 EUR</title>"
index? pos1 ;== 8
pos2 ;== "</title>"
index? pos2 ;== 30

However, this is not yet very useful. How do we get the data in between the <title> and </title> tags? This is done with the copy word:

parse rate [thru "<title>" copy data to "</title>" to end]    ;== true

Now data contains what we need:

print data   ;1 USD = 0.81191502 EUR

(Use probe instead of print to see the type of data; here, it is a simple string.)

copy is always followed by a variable (here, data) and precedes a match rule (here, to "</title>").

copy extracts the whole matched string. When you need only the first character, use set:

parse rate [thru "<title>" set data to "</title>" (print data) to end]
; 1 ;== true

Now try to parse the data string to extract the exchange rate 0.81191502  yourself (see question 6 in the Questions section). If you didn't find it, make sure you understand the solution.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.161.225