Language reference
This document describes the syntax and semantics of the custom language used in ransack.
Basic data types
Number
Numbers can be represented as integers, floating-point values, or in scientific notation.
Examples:
27
, -15
, 3.14
, 2e25
, 2.15e-17
String
A sequence of characters enclosed in single or double quotes.
Examples:
"hello"
, 'world'
Datetime
Combination of date and time, optionally joined by T
.
Date:
YYYY-MM-DD
Time:
HH:MM:SS[.fraction][Z|(+|-)HH:MM]
If the time component is omitted, it defaults to midnight.
Examples:
2025-04-11T14:30:00
, 2025-04-11 14:30:00Z
, 2025-04-11
,
2025-04-11T14:30:00+07:00
Timedelta
Represents a time interval. An optional number of days (d
or D
) may precede the required
time component (HH:MM:SS
).
Examples:
1D12:00:00
, 23:59:59
IPv4 & IPv6
Supports individual addresses, ranges, and CIDR notation.
Examples:
192.168.1.1
, 192.168.1.1-192.168.1.100
, 192.168.1.0/24
2001:db8::1
, 2001:db8::1-2001:db8::ff
, 2001:db8::/64
Warning
IP addresses in quotation marks (e.g., "192.168.0.1"
) are recognized as strings.
That is, they are no longer recognized as IP addresses!
Variables
Alphanumeric with optional dots, underscores, or hyphens.
Examples:
Source.IP4
, .Description
Context
The parser accepts an optional context dictionary at initialization, allowing users to define static variables that can be referenced in queries.
Context variables:
Are separate from input data.
Take precedence over similarly named data variables.
Allow for reusable query logic.
To resolve ambiguity, a prefixing convention is used:
Variables prefixed with a dot (e.g.,
.foo
) are explicitly taken from the input data.Variables without a prefix (e.g.,
foo
) are looked up in the context if available.
Example:
ctx = {"threshold": 100}
parser = Parser(context=ctx)
parser.parse("threshold > .load") # Context variable vs data variable
Functions
Functions use parentheses and comma-separated arguments.
For the full list and documentation of available functions, see ransack.function module.
Functions return either a basic data type or a collection.
Examples:
len(Source.IP4)
, now()
Collections
List
Comma-separated values in square brackets.
Examples:
[1, 2, 3.0]
, [192.168.0.1, 192.168.0.0/24]
Range
Defines an inclusive sequence of numbers, datetimes, or IP addresses.
Examples:
1..1024
, 1.0 .. 0
, 2025-01-01 .. 2025-12-31
Operators
Arithmetic operators
Operator |
Operand Types |
Result Type |
Description |
---|---|---|---|
|
|
|
Standard numeric addition |
|
|
Adds duration to datetime |
|
|
|
Adds two time intervals |
|
|
|
|
Standard numeric subtraction |
|
|
Subtracts duration from datetime |
|
|
|
Subtracts two time intervals |
|
|
|
Time difference between two datetimes |
|
|
|
|
Scales a time interval |
|
|
Standard numeric multiplication |
|
|
|
|
Ratio of two time intervals |
|
|
Standard numeric division |
|
|
|
|
Remainder of timedelta division |
|
|
Standard numeric modulo |
Basic data type vs. collection: Operation is applied element-wise.
Collection vs. collection: Disallowed.
Comparison operators
=
: Loose equality==
: Strict equality>
/>=
: Greater than / Greater than or equal<
/<=
: Less than / Less than or equal
Comparisons are valid for numbers, datetimes, timedeltas, and IP addresses.
Collections: True if any element satisfies the comparison.
Comparing two collections is treated as: “Does any element in the left collection match any element in the right collection?”
Warning
The ==
operator now represents strong equality, in contrast to the older behavior where it also matched elements within collections.
To support collection-aware comparisons, a new =
operator has been introduced. This operator returns True
if any element in the collection satisfies the comparison — mirroring the behavior of >
, >=
, <
, and <=
.
For example:
1 == [1, 2] # False
1 = [1, 2] # True
This change promotes consistency across all comparison operators, but be aware that it may lead to different results if you previously relied on ==
for implicit collection matching.
Special operators
in operator
Tests membership. Returns true if the left-hand element exists in the right-hand side (collection or IP/CIDR range). Recurses into nested collections.
contains operator
String containment check.
Example:
"abcdef" contains "abc"
→ True
Warning
"abc" in ["abcdef", "cccabcddd"]
→ False
?? operator
Existence/default fallback operator.
Unary:
var??
— checks if a variable exists.Binary:
var ?? default
— returnsdefault
ifvar
is not found.
Examples:
Description??
, foo ?? "default"
, Source.Port??[]
. (Concatenation)
Used to concatenate strings or merge lists.
Examples:
'abc'.'def'
, [1, 2, 3] . [4, 5, 6]
.. (Range)
Defines a range between two values (inclusive).
Examples:
1 .. 13
, 1..Source.Port
, 192.168.0.1..192.168.0.255
Logical operators
and
/&&
: Logical ANDor
/||
: Logical ORnot
/!
: Logical NOT
Return a boolean.
Evaluation order (precedence)
From highest to lowest:
Parentheses
()
Unary minus
-
Existence
??
Multiplicative:
*
,/
,%
Additive:
+
,-
Concatenation / Range:
.
,..
Comparison:
=
,==
,>
,<
,>=
,<=
,in
,contains
Logical NOT:
!
,not
Logical AND:
&&
,and
Logical OR:
||
,or
Examples
(3 + 4) * 2
"tcp" in Source.Proto??[]
not (Format == "IDEA0")
Source.IP4 = 192.168.0.1 or Source.IP4 in 10.0.0.0/8