Skip to content

String Operations in Expression Language

Overview

String operations provide powerful text manipulation and matching capabilities in the expression language. These operations are essential for filtering and querying text-based data with precise control over string matching patterns.

Available Operations

1. String Contains (includes)

The includes operator checks if a string contains another string as a substring.

js
description includes "error"
message includes "warning"

Implementation Details

  • Case-sensitive matching
  • Returns false if either operand cannot be converted to a string
  • Uses Go's strings.Contains() under the hood
  • Handles any value that can be converted to a string

Example with different types:

js
// Basic string contains
text includes "search"

// With number conversion
code includes "123"

// With mixed types
message includes "404"  // Works with automatic string conversion

2. String Starts With (starts)

The starts operator checks if a string begins with a specified prefix.

js
filename starts "log_"
email starts "admin@"

Implementation Details

  • Case-sensitive prefix matching
  • Uses Go's strings.HasPrefix() internally
  • Returns false if either operand cannot be converted to a string
  • Efficient prefix checking without scanning entire string

Example patterns:

js
// File type checking
filename starts "backup_"

// Protocol checking
url starts "https://"

// Category filtering
category starts "PROD_"

3. String Ends With (ends)

The ends operator verifies if a string ends with a specified suffix.

js
filename ends ".pdf"
domain ends ".com"

Implementation Details

  • Case-sensitive suffix matching
  • Uses Go's strings.HasSuffix() internally
  • Returns false if either operand cannot be converted to a string
  • Efficient suffix checking without scanning entire string

Common use cases:

js
// File extension filtering
document ends ".docx"

// Domain validation
email ends "@company.com"

// Version checking
version ends "-SNAPSHOT"

4. Regular Expression Matching (match)

The match operator provides powerful pattern matching using regular expressions.

js
// Basic pattern matching
username match "^[a-zA-Z0-9_]+$"

// Email pattern validation
email match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"

Implementation Details

  • Uses Go's regexp package for pattern matching
  • Compiles regex pattern once for efficiency
  • Returns false and error for invalid regex patterns
  • Supports full Go regular expression syntax

Advanced patterns:

js
// IP address matching
ip match "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"

// Date format validation
date match "^\\d{4}-\\d{2}-\\d{2}$"

// Complex text patterns
log match "ERROR|FATAL|CRITICAL"

Type Handling

All string operations handle type conversion automatically through the following rules:

  1. String values are used directly
  2. Values implementing fmt.Stringer interface use their String() method
  3. Other types are converted using fmt.Sprintf("%v")

This flexible type handling allows operations to work with various data types:

js
// Works with numbers
id includes "123"

// Works with boolean values
status includes "true"

// Works with custom types that implement fmt.Stringer
customObject includes "specific-value"

Using NOT with String Operations

All string operations can be negated using the NOT operator:

js
// Negated contains
message NOT includes "error"

// Negated prefix
filename NOT starts "temp_"

// Negated suffix
email NOT ends "@test.com"

// Negated regex match
username NOT match "^admin.*"

Best Practices

  1. Case Sensitivity

    • Remember all operations are case-sensitive
    • Use regex with (?i) flag for case-insensitive matching when needed
  2. Performance Considerations

    • starts and ends are more efficient than includes for prefix/suffix checking
    • Prefer specific operators over regex when possible
    • Use match only when complex pattern matching is required
  3. Error Handling

    • Validate regex patterns before deployment
    • Handle potential type conversion edge cases
    • Consider using simpler operators when exact matching isn't required
  4. Pattern Design

    • Keep regex patterns simple and maintainable
    • Document complex patterns with examples
    • Consider using named capture groups in regex for clarity

Examples in Context

Log Analysis

js
// Filter error messages
message includes "Exception"
stacktrace includes "NullPointerException"

// Identify specific log formats
logline starts "[ERROR]"
logline match "\\[\\d{4}-\\d{2}-\\d{2}\\]"

File Operations

js
// Filter by file type
filename ends ".pdf"
filename ends ".docx"

// Validate file naming conventions
filename match "^PROJECT-\\d{4}-.*\\.txt$"

Email Filtering

js
// Domain filtering
email ends "@company.com"
email NOT ends "@competitor.com"

// Email pattern validation
email match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"

URL Processing

js
// Protocol verification
url starts "https://"
url NOT starts "http://"

// Domain validation
url match "^https://[a-zA-Z0-9.-]+\\.company\\.com/.*$"