--- title: "substring-before()" description: "Returns the part of a string that appears before the first occurrence of a given separator substring." date: 2026-04-18T00:00:00Z version: "1.0" versionLabel: "XSLT 1.0" category: "string function" syntax: "substring-before(string, separator)" tags: ["xslt", "reference", "xpath", "xslt1"] --- ## Description `substring-before()` finds the first occurrence of `separator` in `string` and returns everything that precedes it. If `separator` is not found, the function returns the empty string `""`. If `separator` is the empty string, the function also returns `""`. Both arguments are converted to strings before processing. The search is case-sensitive. `substring-before()` is the XPath 1.0 way to split a delimited string and extract the left-hand portion: usernames from `user@host` addresses, keys from `key=value` pairs, or path segments from URIs. ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `string` | xs:string | Yes | The string to search within. | | `separator` | xs:string | Yes | The delimiter to search for. | ## Return value `xs:string` — the portion of `string` before the first occurrence of `separator`, or `""` if not found. ## Examples ### Extract username from an email address **Input XML:** ```xml ``` **Stylesheet:** ```xml ``` **Output:** ```xml alice bob.smith ``` ### Extract key from a key=value pair **Input XML:** ```xml color=blue size=large weight=1.5kg ``` **Stylesheet:** ```xml ``` **Output:** ```xml colorblue sizelarge weight1.5kg ``` ## Notes - If `separator` does not appear in `string`, `substring-before()` returns `""` — not the original string. Use `contains()` first if you need to distinguish the "not found" case. - Only the **first** occurrence of `separator` is used. To split on the last occurrence, combine `substring-before()` with `substring-after()` and recursive templates or iterate with the `translate()` trick in XSLT 1.0. - `substring-before($s, '')` returns `""` as specified; this is a common source of confusion. - In XSLT 2.0+, `tokenize()` provides a cleaner way to split strings on delimiters, including regex-based separators. ## See also - [substring-after()](../xpath-substring-after) - [starts-with()](../xpath-starts-with) - [contains()](../xpath-contains) - [substring()](../xpath-substring)