---
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)