XQuery - How do I extract a substring before the second occurrence of a character?

Let's say I have this string: "123_12345_123456"

I would like to extract everything before the second "_" (underscore)

I tried:

fn:tokenize("123_1234_12345", '_')[position() le 2]

That returns:

123
1234

What I actually want is:

123_1234

How do I achieve that?

I am using XQuery 1.0


Solution 1:

Regular expressions are flexible and compact:

replace('123_1234_12345', '_[^_]+$', '')

Another solution that may be better readable is to a) tokenize the string, b) keep the tokens you want to preserve and c) join them again:

string-join(
  tokenize('123_1234_12345', '_')[position() = 1 to 2],
  '_'
)

Solution 2:

Taking the basic idea from Michael Kay's deleted answer, it could be implemented like this:

substring($input, 1, index-of(string-to-codepoints($input), 95)[2] - 1)