Split String from an URL

Dear ODK community,

In ODK collect I need to take an answer and store it in two different
variables. The variables shall be calculated by spliting the answer at a
slash "/"

Hopefully someone can help me out !

substring-after is likely what you need, but you won't be able to use

substring-after(${your-url-field} , '/')

as there are other / in the string already (https://). Hopefully your URL has a known form, then you can make your target more specific, eg

substring-after(${your-url-field} , 'split-string-from-an-url/') would return 54822 from this thread URL string.

Edited to fix string/target order

dear @ahblake ,
Thank you for your support
Please, let Me be more specific :
my url is : https://webapps01/Home/Mag/kilo22072021123937363
my wish is to extract kilo22072021123937363 and save It in other fild.
in attached, an overview of the form
Regards

Ok, if your URL in field ${id_barcode}always begins with https://webapps01/Home/Mag/ and the part at the end that changes that you want is, for example kilo22072021123937363, then you can get that either as a calculate field, or with a calculate into a text field with;

substring-after(${id_barcode} , 'https://webapps01/Home/Mag/')

or even

substring-after(${id_barcode} , 'Mag/')

1 Like

Thank you very much

It is working perctly

1 Like

For a more dynamic formula that takes the string after the last “/”. This solution is not pretty, but basically it counts how many “/” occur in the URL string and uses nested if statements to make a a specific calculation for each differing number of “/”. Not ideal for super large variations, but this should be plenty fine for most people who want to extract the end of the string after the nth occurrence of a certain character within reasonable quantities.

Column 1 Column 2 Column 3 E
type name label::English (en) calculation
barcode barcode1 Scan Barcode 1.31
calculate calc_b1_slash_count string-length(${barcode1}) - string-length(translate(${barcode1}, '/', ''))
calculate calc_ID_from_URL if(${calc_b1_slash_count} = 3, substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), if(${calc_b1_slash_count} = 4, substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), if(${calc_b1_slash_count} = 5, substring-after(substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), '/'), if(${calc_b1_slash_count} = 6, substring-after(substring-after(substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), '/'), '/'), if(${calc_b1_slash_count} = 7, substring-after(substring-after(substring-after(substring-after(substring-after(substring-after(substring-after(${barcode1}, '/'), '/'), '/'), '/'), '/'), '/'), '/'), '' ) ) ) ) )

I like @ahblake’s solution since the format is known and consistent!

@Tyler_Depke is right that sometimes a more dynamic approach might be needed. One tip I think you’ll all like is that there’s a lot that can be done with space-separated lists because that’s the format of select multiple answers. I’ve seen @ahblake do some pretty creative things with that.

In this case, I think you can use the translate function to replace “/” with “ “ and store the result in a calculate named something like url_parts. Then you can selected-at on url_parts with an index of count-selected(url_parts) - 1. That’s very similar to @Tyler_Depke’s approach but takes advantage of the fact that we can request an element at a specific position when we have a space-separated list.

I’ve filed an issue to mention space-separated lists more explicitly in docs https://github.com/getodk/docs/issues/1989

1 Like

The exact formula as @LN describes works beautifully and here it is exactly:

selected-at(translate(${barcode1},"/"," "),count-selected(translate(${barcode1},"/"," "))-1)

1 Like