XQuery and XPath Regular Expressions (original) (raw)
The W3C standard for XQuery 1.0 and XPath 2.0 Functions and Operators defines three functions fn:matches, fn:replace and fn:tokenize that take a regular expression as one of their parameters. The XQuery and XPath standard introduces a new regular expression flavor for this purpose. This flavor is identical to the XML Schema flavor, with the addition of several features that are available in many modern regex flavors, but not in the XML Schema flavor. All valid XML Schema regexes are also valid XQuery/XPath regexes. The opposite is not always true.
Because the XML Schema flavor is only used for true/false validity tests, these features were eliminated for performance reasons. The XQuery and XPath functions perform more complex regular expression operators, which require a more feature-rich regular expression flavor. That said, the XQuery and XPath regex flavor is still limited by modern standards.
XQuery and XPath support the following features on top of the features in the XML Schema flavor:
- ^ and $ anchors that match at the start or end of the string, or the start or end of a line (see matching modes below). These are the only two anchors supported.
- Lazy quantifiers, using the familiar question mark syntax.
- Backreferences and capturing groups. The XML Schema standard supports grouping, but groups were always non-capturing. XQuery/XPath allows backreferences to be used in the regular expression. fn:replaces supports backreferences in the replacement text using the $1 notation.
While XML Schema allows no matching modes at all, the XQuery and XPath functions all accept an optional flags parameter to set matching modes. Mode modifiers within the regular expression are not supported. These four matching modes are available:
- i makes the regex match case insensitive.
- s enables “single-line mode”. In this mode, the dot matches newlines.
- m enables “multi-line mode”. In this mode, the caret and dollar match before and after newlines in the subject string.
- x enables “free-spacing mode”. In this mode, whitespace between regex tokens is ignored. Comments are not supported.
The flags are specified as a string with the letters of the modes you want to turn on. E.g. "ix" turns on case insensitivity and free-spacing. If you don’t want to set any matching modes, you can pass an empty string for the flags parameter, or omit the parameter entirely.
Three Regex Functions
fn:matches(subject, pattern, flags) takes a subject string and a regular expression as input. If the regular expression matches any part of the subject string, the function returns true. If it cannot match at all, it returns false. You’ll need to use anchors if you only want the function to return true when the regex matches the entire subject string.
fn:replace(subject, pattern, replacement, flags) takes a subject string, a regular expression, and a replacement string as input. It returns a new string that is the subject string with all matches of the regex pattern replaced with the replacement text. You can use 1to1 to 1to99 to re-insert capturing groups into the replacement. $0 inserts the whole regex match. Literal dollar signs and backslashes in the replacement must be escaped with a backslash.
fn:replace cannot replace zero-length matches. E.g. fn:replace("test", "^", "prefix") will raise an error rather than returning “prefixtext” like regex-based search-and-replace does in most programming languages.
fn:tokenize(subject, pattern, flags) is like the “split” function in many programming languages. It returns an array of strings that consists of all the substrings in subject between all the regex matches. The array will not contain the regex matches themselves. If the regex matches the first or last character in the subject string, then the first or last string in the resulting array will be empty strings.
fn:tokenize also cannot handle zero-length regular expression matches.