patternMatch
patternMatch(text: String, pattern: Pattern<T>) : T?
Matches pattern against the start of text and returns the data extracted by the pattern, or null if the pattern
does not match.
The type T of the result depends on the pattern:
- A pattern whose named components are not repeated, such as
interface {name:string}, returns a record with one field per name. - A repeated named component, such as
{ids:number+}, returns a list with one record per repetition. See thevlanexamples below. - A pattern with no components, such as
interface, returns the empty record{}. - A pattern with a single unnamed component, such as
{ipv4Subnet}, returns the value of that component.
This function is intended to be used to match single lines of configuration files. To match multiple lines of configuration, use blockMatches.
See Details on Patterns for the full pattern syntax.
Matching rules
- Leading whitespace in
textis skipped before matching starts. - The pattern must match at the start of
text.patternMatchdoes not search for the pattern later in the text. - Text that remains after the pattern matches is ignored. End the pattern with
{eof}to require that the pattern matches all oftext. - Each literal and each value component, such as
{string}or{number}, must be followed by whitespace or the end oftext. For example, the literalinterfacedoes not match"interfaces", and{number}does not match"1000mb". - Literals are case-sensitive.
- Note that the pattern does not need to match the entire input (except when
{eof}terminates the pattern).
Null inputs
If text or pattern is null, the query fails with the error
First argument to “patternMatch” was null; consider adding an isPresent() condition. (or Second argument for
pattern). Use isPresent to exclude null values before calling
patternMatch.
Examples
text | pattern | The result of patternMatch(text, pattern) | Remarks |
|---|---|---|---|
"interface Ethernet1/1" | `interface {name:string}` | {name: "Ethernet1/1"} | The named component name:string adds the field name to the result. string matches all characters up to the next whitespace. |
"interface Ethernet1/1" | `interface` | {} | A pattern with no components extracts no data. A successful match returns the empty record. |
" speed 1000 " | `speed {speed:number}` | {speed: 1000} | Leading and trailing whitespace in text is skipped. number returns an Integer. |
"speed 1000mb" | `speed {speed:number}` | null | number matches only digits, with an optional leading minus sign, up to the next whitespace. 1000mb contains letters, so number does not match it. |
"ip address 10.1.1.1 255.255.255.0" | `ip address {addr:ipv4Address} {mask:ipv4Address}` | {addr: 10.1.1.1, mask: 255.255.255.0} | Each named component adds one field to the result record. |
"ip address 10.1.1.1 255.255.255.0 secondary" | `ip address {addr:ipv4Address}` | {addr: 10.1.1.1} | The pattern only needs to match the start of text. The remaining text, 255.255.255.0 secondary, is ignored. |
"ip address 10.1.1.1 255.255.255.0 secondary" | `ip address {addr:ipv4Address} {eof}` | null | {eof} matches only at the end of text. The text 255.255.255.0 secondary follows the address, so the match fails. |
"vlan 10 20 30" | `vlan {ids:(number+)}` | {ids: [10, 20, 30]} | number+ matches one or more numbers and returns a list. The parentheses apply the name ids to the whole repetition, so the result is one record with a list field. |
"vlan 10 20 30" | `vlan {ids:number+}` | [{ids: 10}, {ids: 20}, {ids: 30}] | Without parentheses, + repeats the named component ids:number. The result is a list with one record per number. |
"10.0.0.0/8" | `{ipv4Subnet}` | 10.0.0.0/8 | A pattern with a single unnamed component returns the value of that component, not a record. The result has type IpSubnet. |
"1.2.3.456/34" | `{ipv4Subnet}` | null | 456 is greater than 255, so it is not a valid IPv4 address octet. /34 is longer than the maximum IPv4 prefix length of 32. |
"interfaces Ethernet1/1" | `interface {name:string}` | null | A literal must be followed by whitespace or the end of text. The literal interface does not match the start of the word interfaces. |
"Interface Ethernet1/1" | `interface {name:string}` | null | Literals are case-sensitive. interface does not match Interface. |
"feature bgp" | `tacacs-server host {name:string}` | null | text does not start with the literal tacacs-server. |
"hello1 hello2 speed 1000 hello3" | `{(!"speed" string)*} speed {speed:number}` | {speed: 1000} | Matches the speed {speed:number} pattern in the middle of the input. The {(!"speed" string)*} pattern matches any number of strings that are not speed. |
Example query
The following query lists the TACACS servers configured on each device. The where isPresent(match) condition keeps
only the config lines that match the pattern.
foreach device in network.devices
foreach line in device.files.config
let match = patternMatch(line.text, `tacacs-server host {server:string}`)
where isPresent(match)
select {device: device.name, tacacsServer: match.server}
To match a pattern against a collection of config lines, use
patternMatches instead. It returns every matching line along
with its extracted data, without a separate isPresent condition.
A pattern can be defined once as a constant and used in several calls:
tacacsPattern = `tacacs-server host {server:string}`;
foreach device in network.devices
foreach line in device.files.config
let match = patternMatch(line.text, tacacsPattern)
where isPresent(match)
select {device: device.name, tacacsServer: match.server}
See also
Guides
- Extracting Data from Configurations via Pattern Matching
- Strings
- Regular Expressions Use regular expressions when you want more control over fine-details of white-space and other aspects of the patterns. Regular expressions are typically more appropriate when extracting information from non-configuration files.
Functions
- patternMatches: Gets all matches of a pattern against a list of config lines, with the matched line and extracted data for each.
- blockMatches: Matches a block pattern against nested config
lines. Unlike
patternMatch,blockMatchesis designed for multi-line pattern-matching. - match: Gets the data captured by a regex, or
nullif the regex does not match. - isPresent: Checks whether a value is not
null.