|
Pages: [1]
|
 |
|
Author
|
Topic: Result from find/any (Read 2481 times)
|
|
bmoore
|
Assuming the following statement is successful and does find a match
find/any string "(*)"
is there any way to recover the string that was actually found?
Any help would be much appreciated - Thanks
|
|
|
|
|
Logged
|
|
|
|
|
Graham
|
Rebol doesn't have wild card searches anymore
but
result: find/any string "(*)"
should give u want you want.
|
|
|
|
|
Logged
|
|
|
|
|
bmoore
|
Thanks for the reply Graham...
When you say Rebol doesn't have wild card searches anymore, are you saying this is a feature that is going away in Rebol 3.0?
The statement:
find/any string "(*)"
does work at the moment!
The statement:
result: find/any string "(*)"
does return the beginning of the string, but it contains a lot of garbage after the match. For such a neat langage that can do so much so easily, I'm surprised that a simple thing like getting the exact match isn't built in. I would think the parsing code would have to know exactly where the string ends and/or the length of the match.
How would I exctract the characters between the two brackets?
|
|
|
|
|
Logged
|
|
|
|
|
Graham
|
Sorry, I was thinking of something else.
I'm not clear as to what you want to do.
|
|
|
|
|
Logged
|
|
|
|
|
bmoore
|
I was trying to get the text between paired brackets.... finally found the answer
parse datastring [thru "(" copy sender-info to ")" skip to end]
Now is there a way to do this for an unknown number of repetitions?
i.e. Extract the data items in brackets where the number of bracket pairs and the format of the data and the junk are not known.
string: {some junk (Data) more junk (More Data) more unknown junk (more data) ....}
The above code will return Data to sender-info, but I don't know an elegant way to get at (More Data) and (more data).
There are some interesting tutorials on Parse, but they don't really spend much time on a very common "real world" type of problems--like pulling stuff out between delimiters (with the exception of web pages where "tags" are delimiters). If anyone knows a reference, that would be helpful as well.
|
|
|
|
« Last Edit: August 10, 2006, 09:19:46 AM by bmoore »
|
Logged
|
|
|
|
|
rebolek
|
Hi bmoore,
if you want to look for unknown number of repetitions use 'any. Also you have to use some block, where you store result. So your code will look like this:
sender-infos: copy [] ;here we'll store results parse datastring [ any [ thru "(" copy sender-info to ")" skip (append sender-infos sender-info) ;this is REBOL code that will be executed after sender-info is found ] to end ]
Hope it helps
|
|
|
|
|
Logged
|
|
|
|
|
Graham
|
Hi bmoore,
if you want to look for unknown number of repetitions use 'any. Also you have to use some block, where you store result. So your code will look like this:
sender-infos: copy [] ;here we'll store results parse datastring [ any [ thru "(" copy sender-info to ")" skip (append sender-infos sender-info) ;this is REBOL code that will be executed after sender-info is found ] to end ]
Hope it helps
Rebolek's code will fail if the text to be parsed ends with a ")" - I think! sender-infos: copy [] ;here we'll store results between-rule: [ thru "(" copy sender-info to ")" (append sender-infos sender-info) ;this is REBOL code that will be executed after sender-info is found skip ; put the skip to step over the ")" after we save the data ] parse datastring [ any between-rule to end ]
|
|
|
|
|
Logged
|
|
|
|
|
rebolek
|
Graham, it's true I didn't test the code  but it seems to be working: >> si: copy [] parse "(aa)(bb)(cc)" [any [thru "(" copy i to ")" skip (append si i)] to end] == true >> si == ["aa" "bb" "cc"]
|
|
|
|
|
Logged
|
|
|
|
|
Graham
|
Hi Rebolek
Good to know that skip will cross over to end :mellow:
|
|
|
|
|
Logged
|
|
|
|
|
bmoore
|
>> si: copy [] parse "(aa)(bb)(cc)" [any [thru "(" copy i to ")" skip (append si i)] to end] == true >> si == ["aa" "bb" "cc"]
Thanks to all who responded... I'd like to especially complement "rebolek" on a really elegant piece of code. It's super tight, and it seems to work well... I've tried several different strings on it, and it worked as it should. I messed around with it a bit, and shortened it even more to: fdata: copy [] parse datastring [any [thru "(" copy i to ")" (append fdata i)] ] I'm just wondering if anyone can tell me if my chages are likely to cause problems? I know the search may return false, but length? fdata is the important thing to test. Thanks again to all.
|
|
|
|
|
Logged
|
|
|
|
|
rebolek
|
bmoore:
The only difference is that 'parse will return 'false instead of 'true. With such a simple rule it's probably not a problem, but if you've got some more complicated rule and you want to be sure that 'parse really reached the end, it's better to use [to end] for safety.
|
|
|
|
|
Logged
|
|
|
|
|
Anton
|
PARSE is probably better in this case, but here's how I might approach it using FIND.
string: "...(hello)...(there)..." ; the input string
result: copy [] use [pos end][ end: string ; set the "end of the last search" to the beginning of the input while [pos: find/tail end "("][ ; while we can find the position just after an opening bracket end: find pos ")" ; find, starting at the position just found, the next closing bracket append result copy/part pos end ; keep a copy of the text between these two positions ] ] print mold result ; ---> ["hello" "there"]
|
|
|
|
|
Logged
|
|
|
|
|
|
Pages: [1]
|
|
|
 |
News: 01-09-08 Alpha version of REBOL 3 has been released!
2243 Posts in 587 Topics by 2010 Members
Latest Member: techpon
|