Home   Archive   Permalink

Divide a string on the first digit

I know how to "brute-force" this but I am thinking it should be handled by "parse" but I don't quite see how, and I wonder if someone might guide me.
I have input strings that are 99+% names and addresses in this form:
"John Smith 123 Main St Hometown MN 55431"
In other words, a name and an address, and the beginning of the address is indicated by the first digit of a house number. Almost every string is like this, and the ones that are not can be handled manually.
So I want to divide a string like this into two strings. The first will be everything from the first character UP TO the first digit (and then trimmed of trailing spaces as an extra step), and the second string will be everything FROM the first digit to the end. In the above example this would produce:
FIRST-STRING: "John Smith"
SECOND-STRING: "123 Main St Hometown MN 55431"
Can this be done by parsing?
Thank you.

posted by:   Steven White       27-Oct-2017/13:08:29-7:00

It can be done by parsing. Can also be done using FIND:
>> address-line: "John Smith 123 Main St Hometown MN 55431"
== "John Smith 123 Main St Hometown MN 55431"
>> digit: charset "0123456789"                            
== make bitset! #{
>> address: copy find address-line digit
== "123 Main St Hometown MN 55431"
>> name: trim/tail copy/part address-line find address-line address
== "John Smith"

posted by:   Chris       27-Oct-2017/13:49:20-7:00

I like to mark the index of the found value, so that a second search doesn't need to be performed:
a: "John Smith 123 Main St Hometown MN 55431"
num: charset [#"0" - #"9"]
name: copy/part a (i: index? find a num) - 2
address: at a i

posted by:   Nick       2-Nov-2017/23:20:25-7:00

Just for fun, here's another way:
name: "" address: "" flag: yes
foreach c "John Smith 123 Main St Hometown MN 55431" [
    if flag [if find "0123456789" c [flag: no]]
    either flag [append name c][append address c]
probe name probe address halt

posted by:   Nick       4-Nov-2017/1:19:10-7:00

And to keep Chris happy :)
flag: yes a: "John Smith 123 Main St Hometown MN 55431"
name: collect [
    foreach c a [
     if find "0123456789" c [break]
     keep c
address: at a (length? name) + 1
probe to-string name probe address halt
(Chris, I have all the respect in the world for you! I hope this will be taken in fun.)

posted by:   Nick       4-Nov-2017/9:22:10-7:00