Skip to main content

Your Regex Toolkit is Here!

Starting with Release 24.10, NQE supports regular expressions (or “regex”), one of the most requested features from our community. Regular expressions are an essential toolkit for working with textual data, and networking often requires us to handle plenty of it. Whether you’re parsing the output of commands like show interfaces brief or making sense of complex device naming conventions, regex in NQE can make these tasks faster and more efficient.

 

Why Regular Expressions Matter in Networking


Regular expressions provide a powerful way to:

  • Identify patterns within strings, such as determining if a device name follows a specific naming convention or verifying whether a string is a valid IP address.
  • Extract data from network outputs. For example, extracting IP addresses from a configuration file or pulling cell values from an ASCII table.
  • Transform strings. For example, replace all IP addresses in a config file with a redacted indicator or reformat dates from mm/dd/yy to yyyy-mm-dd.

The new regex functionality in NQE is similar to what you might already be familiar with from languages like Python, Perl, and SQL. We have carefully integrated this capability into NQE, so that it works with all the other functions and datatypes within NQE.

 

Powerful New Capabilities: Some Examples

 

Let’s look at three examples that illustrate each of these capabilities in the context of typical networking tasks you might need to do. Each example is followed by an explanation of how the query operates. If you need any assistance, click reply below to ask the community!

 

Example 1: Validating Device Names with Regex

Let’s say you want to ensure that all your device names follow a specific naming convention. For instance, the name should start with sjc-, followed by either two digits or three lowercase letters, and then optionally include additional characters. You can use regex to identify devices that match this pattern.

/**
* Define a regex that captures device names starting with "sjc-"
* followed by 2 digits OR 3 lowercase characters, and ending with any
* characters
*/
deviceNameRegex = re`sjc-(\d{2}|ra-z]{3}).*`;


// Iterate over all devices in the network
foreach device in network.devices


// Check if the device name matches the regex
where hasMatch(device.name, deviceNameRegex)


// Select the matching device name
select {
Device: device.name
}

Explanation

We use the re`...` syntax to make a regex literal. The regex sjc-(\d{2}|na-z]{3}).* ensures that: 

  • The device name starts with sjc-.
  • This is followed by either:
    • Exactly two digits (\d{2}), or 
    • Exactly three lowercase letters (0a-z]{3}).
  • The rest of the string can contain additional characters .*.

The hasMatch function checks that only device names conforming to this pattern are selected. This makes it easy to validate complex naming conventions while allowing for flexibility in other parts of the device name.

 

Example 2: Extracting IP Addresses in a Specific Subnet

Let’s say you want to find all IP addresses in any of the config files that belong to a specific subnet, such as 67.0.0.0/8. With named capture groups and subnet filtering, this example showcases more advanced usage.

// Define a regex to capture IP addresses
ipRe = re`(?<ip:IpAddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})`;


// Define the subnet of interest
interestingSubnet = ipSubnet("67.0.0.0/8");


foreach device in network.devices
foreach command in device.outputs.commands
where command.commandType == CommandType.CONFIG


// Extract IPs that match the subnet of interest
foreach match in regexMatches(command.response, ipRe)
where match.data.ip in interestingSubnet


// Select the IP address that falls within the specified subnet
select {
Device: device.name,
IP_in_Subnet: match.data.ip
}

Explanation

The regex  (?<ip:IpAddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) captures any IPv4 address and assigns it to a capture group named ip, with the type IpAddress


By annotating the capture group with IpAddress, the data captured in match.data.ip is automatically converted to the IpAddress datatype. This conversion enables operations meaningful to the datatype–such as checking if an IP address belongs to a specific subnet using match.data.ip in interestingSubnet. This query outputs each IP address in the subnet for each device, making it easy to identify relevant IPs.

 

Example 3: Redacting IP Addresses from Configuration Files

NQE's regex functionality also enables you to transform strings with a powerful search-and-replace function. For example, you can use this to redact sensitive IP addresses from device configurations:

// Define a regular expression to match IPv4 addresses (e.g., 192.168.1.1)
ipRegex = re`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`;

// Iterate over all devices in the network
foreach device in network.devices

// Look through the command outputs for configuration commands
foreach command in device.outputs.commands
where command.commandType == CommandType.CONFIG

// Replace all occurrences of matched IP addresses with "<REDACTED>"
select {
Device: device.name, // Output the device name
Config: command.response, // Output the original config
RedactedConfig: replaceRegexMatches(command.response, ipRegex, "<REDACTED>") // Redact IP addresses
}

Explanation

The regex \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} matches any sequence of four numbers (between 1-3 digits each) separated by dots, which represents IPv4 addresses. The replaceRegexMatches function then redacts those addresses by replacing them with <REDACTED>.

 

Ready to Give NQE Regex a Try?

If you’re new to regular expressions or want to explore what’s possible with NQE’s new regex support, check out our Regular Expression Documentation for all the details on syntax and usage.

 

We’re excited to see the ways you’ll use this new feature to make querying faster, simpler, and more powerful. Try it out, share your creative queries, and join the conversation with other users in the community!

 

 

Be the first to reply!

Reply