CEL-API-Referenz (Common Expression Language)

Dieses Dokument dient als einheitliche API-Dokumentationsreferenz für die Common Expression Language (CEL). Darin sind alle Makros, Operatoren und Standardfunktionen mit ihren Signaturen, Verhaltensweisen und dem Supportstatus für die offiziellen CEL-Stacks aufgeführt.

Weitere Informationen zum Sprachverhalten und zu den Spezifikationen finden Sie in der CEL-Sprachdefinition.

Stack-Versionen

Dieses Referenzdokument basiert auf den folgenden Versionen der CEL-Stacks:

  • CEL Go: v0.29.2 und höher
  • CEL C++: v0.15.0
  • CEL Java: v0.13.1
  • CEL Python: v0.1.3
  • CEL C: Entwicklungs-Snapshot (nicht veröffentlicht)

GitHub-Spiegelungen

Die offiziellen Implementierungen von CEL werden auf GitHub unter der Organisation cel-expr gespiegelt:


1. Core-Makros

Dies sind integrierte Makros, die zur Kompilierungszeit erweitert werden.

Macro Beschreibung Ok C++ Java Python C
has(container.field) Prüft, ob ein Feld in einer Nachricht oder ein Schlüssel in einer Map vorhanden ist.

Signaturen:
has(container.field) -> bool

Beispiele:
has(request.auth.claims.email)
list.all(var, predicate) Prüft, ob alle Elemente in einer Liste ein Prädikat erfüllen.

Signaturen:
list.all(var, predicate) -> bool

Beispiele:
[1, 2, 3].all(x, x > 0) // true
¹
list.exists(var, predicate) Prüft, ob mindestens ein Element in einer Liste ein Prädikat erfüllt.

Signaturen:
list.exists(var, predicate) -> bool

Beispiele:
[1, 2, 3].exists(x, x > 2) // true
¹
list.exists_one(var, predicate) Prüft, ob genau ein Element in einer Liste ein Prädikat erfüllt.

Signaturen:
list.exists_one(var, predicate) -> bool

Beispiele:
[1, 2, 3].exists_one(x, x == 2) // true
¹
list.filter(var, predicate) Filtert Elemente einer Liste anhand eines Prädikats.

Signaturen:
list.filter(var, predicate) -> list

Beispiele:
[1, 2, 3].filter(x, x > 1) // [2, 3]
¹
list.map(var, transform) Transformiert jedes Element einer Liste mithilfe eines Ausdrucks.

Signaturen
list.map(var, transform) -> list

Beispiele
[1, 2, 3].map(x, x * 2) // [2, 4, 6]
¹
list.map(var, filter, transform) Transformiert Elemente einer Liste, die ein Filterprädikat erfüllen.

Signaturen:
list.map(var, filter, transform) -> list

Beispiele:
[1, 2, 3].map(x, x > 1, x * 2) // [4, 6]
¹

¹ In der C-Laufzeitumgebung unterstützt, da Makros während der Kompilierung vom Hostcompiler in Comprehensions erweitert werden.


2. Kernoperatoren

Operator Beschreibung Ok C++ Java Python C
Arithmetisch (+, -, *, /, %) Standardmäßige arithmetische Operationen. Negation (-x) und Identität (+x). Die Listenverkettung (list + list) wird in Go, C++, Java und Python unterstützt.

Signaturen
T + T -> T
T - T -> T
T * T -> T
T / T -> T
T % T -> T
-T -> T
+T -> T
list + list -> list

Beispiele
1 + 2 * 3 // 7
[1] + [2] // [1, 2]
²
Vergleich (==, !=, <, <=, >, >=) Standardvergleich Numerische Vergleiche sind heterogen (z.B. 1 == 1.0).

Signaturen
T == T -> bool
T != T -> bool
T < T -> bool
T <= T -> bool
T > T -> bool
T >= T -> bool

Beispiele
x < 42.0
1 == 1.0 // true
Logisch (!, &&, ||, ? :) Logisches NICHT, UND, ODER und ternärer bedingter Operator. UND/ODER verwenden Sie die Kurzschlussauswertung.

Signaturen:
!bool -> bool
bool && bool -> bool
bool || bool -> bool
bool ? T : T -> T

Beispiele:
x > 0 ? "positive" : "non-positive"
Indexierung ([]) Greift über den Index auf ein Element einer Liste oder über den Suchschlüssel auf ein Element einer Map zu.

Signaturen:
list[int] -> T
map[K] -> V

Beispiele:
tags[0]
users['john']
Mitgliedschaft (in) Prüft, ob sich ein Element in einer Liste oder ein Schlüssel in einer Zuordnung befindet.

Signaturen:
T in list -> bool
K in map -> bool

Beispiele:
'admin' in roles

² Die Listenverkettung (list + list) wird in der C-Laufzeit nicht unterstützt, andere arithmetische Operatoren jedoch schon.


3. Hauptfunktionen

Allgemeine Funktionen und Stringfunktionen

Funktion Beschreibung Ok C++ Java Python C
size Gibt die Größe eines Strings (Zeichen), von Byte, einer Liste oder einer Map zurück.

Signaturen:
size(T) -> int (wobei T string, bytes, list oder map ist)<br /><br />**Examples:**<br />size("hello") // 5`
contains Gibt zurück, ob ein String einen Teilstring enthält.

Signaturen:
string.contains(string) -> bool

Beispiele:
"hello".contains("ell") // true
startsWith Gibt zurück, ob ein String mit einem Präfix beginnt.

Signaturen:
string.startsWith(string) -> bool

Beispiele:
"hello".startsWith("he") // true
endsWith Gibt zurück, ob ein String mit einem Suffix endet.

Signaturen:
string.endsWith(string) -> bool

Beispiele:
"hello".endsWith("lo") // true
matches Gibt zurück, ob der String mit dem regulären RE2-Ausdruck übereinstimmt.

Signaturen:
string.matches(string) -> bool

Beispiele:
"123".matches(r"^\d+$") // true

Funktionen für die Auswahl von Datum und Uhrzeit

Mit diesen Funktionen werden Komponenten aus google.protobuf.Timestamp oder google.protobuf.Duration extrahiert.

Funktion Beschreibung Ok C++ Java Python C
getFullYear Gibt das vierstellige Jahr zurück.

Signaturen:
timestamp.getFullYear([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026
getMonth Gibt den Monat (0–11) zurück.

Signaturen:
timestamp.getMonth([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getMonth() // 6
getDayOfMonth Gibt den Tag des Monats (1–31) zurück.

Signaturen:
timestamp.getDayOfMonth([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23
getDayOfWeek Gibt den Wochentag zurück (0 = Sonntag).

Signaturen:
timestamp.getDayOfWeek([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4
getDayOfYear Gibt den Tag des Jahres (0–365) zurück.

Signaturen:
timestamp.getDayOfYear([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203
getHours Gibt die Stunden (0–23) zurück.

Signaturen:
timestamp.getHours([tz]) -> int
duration.getHours() -> int

Beispiele:
duration("1h30m").getHours() // 1
getMinutes Gibt die Minuten (0–59) zurück.

Signaturen:
timestamp.getMinutes([tz]) -> int
duration.getMinutes() -> int

Beispiele:
duration("1h30m").getMinutes() // 30
getSeconds Gibt die Sekunden (0–59) zurück.

Signaturen:
timestamp.getSeconds([tz]) -> int
duration.getSeconds() -> int

Beispiele:
duration("1h30m45s").getSeconds() // 45
getMilliseconds Gibt die Millisekunden (0–999) zurück.

Signaturen:
timestamp.getMilliseconds([tz]) -> int
duration.getMilliseconds() -> int

Beispiele:
duration("1.5s").getMilliseconds() // 500

Typkonvertierungen

Zieltyp Beschreibung Ok C++ Java Python C
bool Wird in einen booleschen Wert konvertiert.

Signaturen:
bool(bool) -> bool
bool(string) -> bool

Beispiele:
bool("true") // true
bytes Wird in Byte konvertiert.

Signaturen
bytes(bytes) -> bytes
bytes(string) -> bytes

Beispiele
bytes("hello") // b"hello"
double Konvertiert in einen Gleitkommawert mit doppelter Genauigkeit.

Signaturen:
double(double) -> double
double(int) -> double
double(uint) -> double
double(string) -> double

Beispiele:
double(1) // 1.0
duration Wird in Dauer konvertiert.

Signaturen:
duration(duration) -> duration
duration(string) -> duration

Beispiele:
duration("1.5s") // 1.5s duration
int Wird in eine vorzeichenbehaftete 64-Bit-Ganzzahl umgewandelt.

Signaturen:
int(int) -> int
int(uint) -> int
int(double) -> int (rundet auf null)
int(string) -> int
int(timestamp) -> int (Sekunden seit der Epoche)

Beispiele:
int(1.5) // 1
string Wird in einen String konvertiert.

Signaturen
string(T) -> string (unterstützt bool, int, uint, double, bytes, timestamp, duration)<br /><br />**Examples:**<br />string(1.5) // "1.5"`
timestamp Wird in einen Zeitstempel konvertiert.

Signaturen:
timestamp(timestamp) -> timestamp
timestamp(string) -> timestamp (RFC3339)

Beispiele:
timestamp("2026-07-23T00:00:00Z")
uint Konvertiert in eine vorzeichenlose 64-Bit-Ganzzahl.

Signaturen
uint(uint) -> uint
uint(int) -> uint
uint(double) -> uint
uint(string) -> uint

Beispiele
uint(1) // 1u
dyn Wandelt einen Wert zur Typüberprüfung in den dynamischen Typ um.

Signaturen:
dyn(T) -> dyn

Beispiele:
dyn([1, "two"])
type Gibt den Typ des Werts zurück.

Signaturen:
type(T) -> type

Beispiele:
type(1) // int

4. Erweiterungen (Bibliotheken)

Bindings Library

Funktion Beschreibung Ok C++ Java Python C
cel.bind Bindet eine lokale Variable, um eine doppelte Auswertung zu vermeiden.

Signaturen:
cel.bind(varName, initExpr, resultExpr) -> T

Beispiele:
cel.bind(x, a + b, x * x)
(v0.15.0) (v0.10.0) (v0.2.0) (v0.1.1)

Aktivierung

Encoders Library

Funktion Beschreibung Ok C++ Java Python C
base64.encode Codiert Bytes in einen Base64-String.

Signaturen:
base64.encode(bytes) -> string

Beispiele:
base64.encode(b"hello") // "aGVsbG8="
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
base64.decode Decodiert einen Base64-String in Byte. Gibt bei ungültiger Eingabe einen Fehler aus.

Signaturen:
base64.decode(string) -> bytes

Beispiele:
base64.decode("aGVsbG8=") // b"hello"
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
json.encode Serialisiert einen CEL-Wert in einen JSON-String.

Signaturen:
json.encode(dyn) -> string

Beispiele:
json.encode([1, 2]) // "[1,2]"
(v0.29.0)

Aktivierung

Math-Bibliothek

Funktion Beschreibung Ok C++ Java Python C
math.greatest Gibt den größten der numerischen Argumente (oder der Liste von numerischen Werten) zurück.

Signaturen:
math.greatest(arg, ...) -> T

Beispiele:
math.greatest(1, 3, 2) // 3
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.least Gibt den kleinsten der numerischen Argumente (oder eine Liste von numerischen Werten) zurück.

Signaturen:
math.least(arg, ...) -> T

Beispiele:
math.least([1, 3, 2]) // 1
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.abs Absolutwert.

Signaturen:
math.abs(T) -> T (unterstützt int, uint, double)<br /><br />**Examples:**<br />math.abs(-1) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sqrt Quadratwurzel.

Signaturen:
math.sqrt(T) -> double (unterstützt int, uint, double)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0`
(v0.25.1) (v0.12.0) (v0.11.0) (v0.1.1)
math.bitAnd Bitweises AND.

Signaturen
math.bitAnd(T, T) -> T (unterstützt int, uint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitOr Bitweises ODER.

Signaturen:
math.bitOr(T, T) -> T (unterstützt int, uint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitXor Bitweises XOR.

Signaturen
math.bitXor(T, T) -> T (unterstützt int, uint)<br /><br />**Examples:**<br />math.bitXor(5, 3) // 6`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitNot Bitweises NOT.

Signaturen:
math.bitNot(T) -> T (unterstützt int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftLeft Bitweise Linksverschiebung.

Signaturen:
math.bitShiftLeft(T, int) -> T (unterstützt int, uint)<br /><br />**Examples:**<br />math.bitShiftLeft(1, 2) // 4`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftRight Bitweise Rechtsverschiebung.

Signaturen:
math.bitShiftRight(T, int) -> T (unterstützt int, uint)<br /><br />**Examples:**<br />math.bitShiftRight(4, 2) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.ceil Aufrunden.

Signaturen
math.ceil(double) -> double

Beispiele
math.ceil(1.2) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.floor Abrunden.

Signaturen:
math.floor(double) -> double

Beispiele:
math.floor(1.8) // 1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.round Runden auf die nächste Ganzzahl.

Signaturen
math.round(double) -> double

Beispiele
math.round(1.5) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.trunc Kürzung (Richtung null).

Signaturen:
math.trunc(double) -> double

Beispiele:
math.trunc(-1.8) // -1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isInf Prüft, ob „double“ positiv oder negativ unendlich ist.

Signaturen:
math.isInf(double) -> bool

Beispiele:
math.isInf(1.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isNaN Prüft, ob der Double-Wert „NaN“ ist.

Signaturen:
math.isNaN(double) -> bool

Beispiele:
math.isNaN(0.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isFinite Prüft, ob der Double-Wert endlich ist.

Signaturen
math.isFinite(double) -> bool

Beispiele
math.isFinite(1.2) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sign Gibt das Vorzeichen des Werts zurück (-1, 0 oder 1).

Signaturen
math.sign(T) -> T (unterstützt int, uint, double)<br /><br />**Examples:**<br />math.sign(-42) // -1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

Aktivierung

Protos-Bibliothek

Funktion Beschreibung Ok C++ Java Python C
proto.getExt Ruft das Proto2-Erweiterungsfeld ab oder den Standardwert, wenn es nicht festgelegt ist.

Signaturen:
proto.getExt(msg, extName) -> T

Beispiele:
proto.getExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
proto.hasExt Prüft, ob das Proto2-Erweiterungsfeld festgelegt ist.

Signaturen:
proto.hasExt(msg, extName) -> bool

Beispiele:
proto.hasExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)

Aktivierung

  • Go:Leite den Pass ext.Protos() an cel.NewEnv() weiter.
  • C++:Fügen Sie ProtoExtCompilerLibrary() zu CompilerBuilder hinzu. Die Laufzeit wird automatisch verwaltet.
  • Java:Fügen Sie CelExtensions.protos() zu CelCompiler- und CelRuntime-Buildern hinzu.
  • Python:Importieren Sie cel_expr_python.ext.ext_proto und verwenden Sie ExtProto() in cel.NewEnv(extensions=[...]).

Listenbibliothek

Funktion Beschreibung Ok C++ Java Python C
distinct Gibt eindeutige Elemente zurück.

Signaturen
list.distinct() -> list

Beispiele
[1, 2, 2].distinct() // [1, 2]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
flatten Verschachtelte Listen werden vereinfacht.

Signaturen
list.flatten([depth]) -> list

Beispiele
[[1], [2, 3]].flatten() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.7.1) (v0.1.1)
lists.range Gibt die Liste der Ganzzahlen [0, ..., n-1] zurück.

Signaturen
lists.range(int) -> list(int)

Beispiele
lists.range(3) // [0, 1, 2]
(v0.22.0) (v0.11.0) (v0.10.1) (v0.1.1)
reverse Kehrt die Liste um.

Signaturen:
list.reverse() -> list

Beispiele:
[1, 2].reverse() // [2, 1]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
slice Gibt eine Unterliste zurück (Start inklusive, Ende exklusive).

Signaturen:
list.slice(start, end) -> list

Beispiele:
[1, 2, 3].slice(1, 3) // [2, 3]
(v0.17.0) (v0.11.0) (v0.11.0) (v0.1.1)
sort Sortiert eine Liste vergleichbarer Elemente.

Signaturen:
list.sort() -> list

Beispiele:
[3, 1, 2].sort() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
sortBy Sortiert die Liste nach dem Schlüssel, der aus dem Ausdruck abgeleitet wird.

Signaturen:
list.sortBy(var, expr) -> list

Beispiele:
[{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
first Gibt das erste Element als optional zurück. Erfordert die optionale Erweiterung.

Signaturen
list.first() -> optional

Beispiele
[1, 2].first() // optional(1)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)
last Gibt das letzte Element als optional zurück. Erfordert die optionale Erweiterung.

Signaturen
list.last() -> optional

Beispiele
[1, 2].last() // optional(2)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)

Aktivierung

Sets-Mediathek

Funktion Beschreibung Ok C++ Java Python C
sets.contains Prüft, ob list1 alle Elemente von list2 enthält.

Signaturen:
sets.contains(list1, list2) -> bool

Beispiele:
sets.contains([1, 2], [1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.equivalent Prüft, ob Listen mengenäquivalent sind (dieselben eindeutigen Elemente enthalten).

Signaturen
sets.equivalent(list1, list2) -> bool

Beispiele
sets.equivalent([1, 2], [2, 1, 1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.intersects Prüft, ob Listen mindestens ein gemeinsames Element haben.

Signaturen:
sets.intersects(list1, list2) -> bool

Beispiele:
sets.intersects([1, 2], [2, 3]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)

Aktivierung

  • Go:Leite den Pass ext.Sets() an cel.NewEnv() weiter.
  • C++:
  • Java:Fügen Sie CelExtensions.sets() zu CelCompiler- und CelRuntime-Buildern hinzu.
  • Python:Aktivieren Sie die Funktion über cel.EnvConfig, indem Sie sets der Liste extensions hinzufügen.

Strings-Bibliothek

Funktion Beschreibung Ok C++ Java Python C
charAt Gibt das Zeichen am Index zurück.

Signaturen:
string.charAt(int) -> string

Beispiele:
"hello".charAt(1) // "e"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
indexOf Gibt den Index des ersten Vorkommens des Teilstrings oder -1 zurück.

Signaturen:
string.indexOf(substr, [start]) -> int

Beispiele:
"hello".indexOf("l") // 2
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
lastIndexOf Gibt den Index des letzten Vorkommens des Teilstrings oder -1 zurück.

Signaturen:
string.lastIndexOf(substr, [end]) -> int

Beispiele:
"hello".lastIndexOf("l") // 3
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
join Verkettet Strings.

Signaturen:
list(string).join([separator]) -> string

Beispiele:
["a", "b"].join("-") // "a-b"
(v0.10.0) (v0.10.0) (v0.2.0) (v0.1.1)
split Teilt einen String anhand des Trennzeichens auf.

Signaturen:
string.split(separator, [limit]) -> list(string)

Beispiele:
"a-b".split("-") // ["a", "b"]
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
substring Gibt den Teilstring zurück (Start inklusive, Ende exklusive).

Signaturen:
string.substring(start, [end]) -> string

Beispiele:
"hello".substring(1, 3) // "el"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
trim Entfernt Unicode-Leerzeichen.

Signaturen:
string.trim() -> string

Beispiele:
" hello ".trim() // "hello"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
replace Ersetzt Vorkommen von „old“ durch „new“.

Signaturen:
string.replace(old, new, [limit]) -> string

Beispiele:
"hello".replace("l", "w") // "hewwo"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
reverse Kehrt Unicode-Codepunkte um.

Signaturen:
string.reverse() -> string

Beispiele:
"abc".reverse() // "cba"
(v0.18.0) (v0.14.0) (v0.13.0) (v0.1.1)
lowerAscii Wandelt ASCII-Zeichen in Kleinbuchstaben um.

Signaturen:
string.lowerAscii() -> string

Beispiele:
"Hello".lowerAscii() // "hello"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
upperAscii Konvertiert ASCII-Zeichen in Großbuchstaben.

Signaturen:
string.upperAscii() -> string

Beispiele:
"Hello".upperAscii() // "HELLO"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
quote Maskiert Strings für die sichere Ausgabe.

Signaturen:
strings.quote(string) -> string

Beispiele:
strings.quote("a\tb") // "\"a\\tb\""
(v0.14.0) (v0.14.0) (v0.13.0) (v0.1.1)

Aktivierung

Mediathek mit regulären Ausdrücken

Funktion Beschreibung Ok C++ Java Python C
regex.replace Ersetzt Übereinstimmungen durch einen Ersatzstring (unterstützt Rückverweise).

Signaturen:
regex.replace(target, pat, repl, [limit]) -> string

Beispiele:
regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123"
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extract Gibt die erste Übereinstimmung des Musters zurück (muss eine Erfassungsgruppe haben).

Signaturen:
regex.extract(target, pat) -> optional(string)

Beispiele:
regex.extract("a123b", r"(\d+)") // optional("123")
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extractAll Gibt alle Übereinstimmungen des Musters zurück (muss eine Erfassungsgruppe haben).

Signaturen:
regex.extractAll(target, pat) -> list(string)

Beispiele:
regex.extractAll("a1b2", r"(\d+)") // ["1", "2"]
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)

Aktivierung

Zwei-Variablen-Zusammenfassungen

Macro Beschreibung Ok C++ Java Python C
all Logisches UND über Schlüssel/Index und Wert abkürzen.

Signaturen:
list.all(i, v, pred) -> bool
map.all(k, v, pred) -> bool

Beispiele:
[1, 2].all(i, v, v > 0) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
exists Logisches ODER über Schlüssel/Index und Wert abkürzen.

Signaturen:
list.exists(i, v, pred) -> bool
map.exists(k, v, pred) -> bool

Beispiele:
[1, 2].exists(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
existsOne Prüft, ob genau ein Paar das Prädikat erfüllt.

Signaturen:
list.existsOne(i, v, pred) -> bool
map.existsOne(k, v, pred) -> bool

Beispiele:
[1, 2].existsOne(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformList Wandelt eine Liste/Karte in eine Liste um oder filtert sie.

Signaturen
list.transformList(i, v, [filter], transform) -> list
map.transformList(k, v, [filter], transform) -> list

Beispiele
[1, 2].transformList(i, v, v * 2) // [2, 4]
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMap Transformiert Werte einer Liste/Zuordnung in eine Zuordnung (Schlüssel bleiben unverändert).

Signaturen:
list.transformMap(i, v, [filter], transform) -> map
map.transformMap(k, v, [filter], transform) -> map

Beispiele:
[1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMapEntry Wird in eine Karte umgewandelt.

Signaturen:
list.transformMapEntry(i, v, [filter], transform_entry) -> map
map.transformMapEntry(k, v, [filter], transform_entry) -> map

Beispiele:
[1, 2].transformMapEntry(i, v, {string(v): v * 2}) // {"1": 2, "2": 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)

Aktivierung

Bibliothek für native Typen

Funktion Beschreibung Ok C++ Java Python C
Native Structs Registrieren und Instanziieren von nativen Hosttypen (Go-Structs / Java-POJOs) in CEL.

Beispiele
Account{id: 123} (in CEL instanziertes Java-POJO)
(v0.13.0) (v0.13.0)

Aktivierung

  • Go:Übergeben Sie ext.NativeTypes(...) (mit Reflektortypen) an cel.NewEnv().
  • C++:Nicht unterstützt.
  • Java:Fügen Sie CelExtensions.nativeTypes() (mit Java-Klassen) den Buildern CelCompiler und CelRuntime hinzu.
  • Python:Nicht unterstützt.

Netzwerkbibliothek

Die Netzwerkbibliothek bietet Funktionen zum Parsen, Validieren und Bearbeiten von IP-Adressen und CIDR-Blöcken.

Funktion Beschreibung Ok C++ Java Python C
ip Parst einen String in eine IP-Adresse oder extrahiert die IP-Adresse aus einem CIDR.

Signaturen
ip(string) -> IP
CIDR.ip() -> IP

Beispiele
ip("192.168.0.1")
cidr("192.168.0.0/24").ip()
(v0.29.0)
isIP Prüft, ob ein String eine gültige IP-Adresse ist.

Signaturen:
isIP(string) -> bool

Beispiele:
isIP("192.168.0.1") // true
(v0.29.0)
ip.isCanonical Prüft, ob ein IP-Adressstring im kanonischen Format vorliegt.

Signaturen:
ip.isCanonical(string) -> bool

Beispiele:
ip.isCanonical("192.168.0.1") // true
(v0.29.0)
cidr Parst einen String in einen CIDR-Block.

Signaturen
cidr(string) -> CIDR

Beispiele
cidr("192.168.0.0/24")
(v0.29.0)
isCIDR Prüft, ob ein String ein gültiger CIDR-Block ist.

Signaturen:
isCIDR(string) -> bool

Beispiele:
isCIDR("192.168.0.0/24") // true
(v0.29.0)
containsIP Prüft, ob ein CIDR-Block eine IP-Adresse enthält.

Signaturen:
CIDR.containsIP(IP) -> bool
CIDR.containsIP(string) -> bool

Beispiele:
cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true
(v0.29.0)
containsCIDR Prüft, ob ein CIDR-Block einen anderen CIDR-Block enthält.

Signaturen:
CIDR.containsCIDR(CIDR) -> bool
CIDR.containsCIDR(string) -> bool

Beispiele:
cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true
(v0.29.0)
family Gibt die IP-Familie zurück (4 für IPv4, 6 für IPv6).

Signaturen:
IP.family() -> int

Beispiele:
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast Prüft, ob die IP-Adresse eine globale Unicast-Adresse ist.

Signaturen:
IP.isGlobalUnicast() -> bool

Beispiele:
ip("192.168.0.1").isGlobalUnicast() // true
(v0.29.0)
isLinkLocalMulticast Prüft, ob die IP-Adresse eine Link-Local-Multicast-Adresse ist.

Signaturen:
IP.isLinkLocalMulticast() -> bool

Beispiele:
ip("224.0.0.1").isLinkLocalMulticast() // true
(v0.29.0)
isLinkLocalUnicast Prüft, ob die IP-Adresse eine link-lokale Unicast-Adresse ist.

Signaturen:
IP.isLinkLocalUnicast() -> bool

Beispiele:
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback Prüft, ob die IP-Adresse eine Loopback-Adresse ist.

Signaturen:
IP.isLoopback() -> bool

Beispiele:
ip("127.0.0.1").isLoopback() // true
(v0.29.0)
isMask Prüft, ob die CIDR eine gültige Subnetzmaske ist.

Signaturen:
CIDR.isMask() -> bool

Beispiele:
cidr("255.255.255.0/24").isMask() // true
(v0.29.0)
isUnspecified Prüft, ob die IP-Adresse eine nicht angegebene Adresse ist (z.B. 0.0.0.0).

Signaturen:
IP.isUnspecified() -> bool

Beispiele:
ip("0.0.0.0").isUnspecified() // true
(v0.29.0)
masked Gibt den maskierten CIDR-Block zurück.

Signaturen:
CIDR.masked() -> CIDR

Beispiele:
cidr("192.168.0.1/24").masked() // 192.168.0.0/24
(v0.29.0)
prefixLength Gibt die Präfixlänge des CIDR-Blocks zurück.

Signaturen:
CIDR.prefixLength() -> int

Beispiele:
cidr("192.168.0.0/24").prefixLength() // 24
(v0.29.0)
string Konvertiert IP-Adressen oder CIDR-Blöcke in Strings.

Signaturen:
string(IP) -> string
string(CIDR) -> string

Beispiele:
string(ip("192.168.0.1")) // "192.168.0.1"
(v0.29.0)

Aktivierung

  • Go:Leite den Pass ext.Network() an cel.NewEnv() weiter.
  • C++:Nicht unterstützt.
  • Java:Nicht unterstützt.
  • Python:Nicht unterstützt.

5. Erweiterte Funktionen

Zusammenfassung der erweiterten Funktionen

Funktion Beschreibung Ok C++ Java Python C
Teilweise Auswertung Auswertung mit fehlenden Eingaben; gibt Unbekannte oder einen vereinfachten Ausdruck zurück. ³
Asynchrone Bewertung Nicht blockierende gleichzeitige Ausführung von Erweiterungsfunktionen.
AST-Validatoren Die statische Analyse wird für den geprüften AST nach der Typüberprüfung durchgeführt.
AST-Optimierungstools AST-Rewrites (Constant Folding, Inlining, CSE), um die Leistung zu verbessern.
CEL Policy Compiler Kompiliert YAML-basierte Richtlinienstrukturen in standardmäßige CEL-ASTs.

³ Go unterstützt das Generieren eines Residual AST (pruned AST). ⁴ C++ und Java unterstützen die Rückgabe von UnknownSet / CelUnknownSet zur Laufzeit, stellen aber keine öffentlichen APIs für die Generierung von Residual-ASTs bereit. ⁵ Go verwendet AsyncBinding / AsyncOp, um Channels zurückzugeben. ⁶ Java verwendet CelAsyncRuntime und gibt ListenableFuture zurück.

Teilweise Auswertung (Unbekannte)

Bei der partiellen Auswertung wird ein Ausdruck ausgewertet, wenn nur eine Teilmenge der Eingabevariablen (Argumente) bekannt ist. Stattdessen wird ein Ergebnis zurückgegeben, das angibt, was fehlt, oder ein vereinfachter Ausdruck.

  • Go:Volle Unterstützung. Ermöglicht die Definition eines PartialActivation mit Mustern unbekannter Attribute. Die Auswertung gibt einen types.Unknown-Wert zurück. Go unterstützt die Generierung eines Residual AST (Env.ResidualAst), einem gekürzten, vereinfachten AST, das nur die Teile des Ausdrucks enthält, die nicht ausgewertet werden konnten.
  • C++:Unterstützt Unknown-Werte. Unbekannte Attributmuster werden über Activation::set_unknown_attribute_patterns konfiguriert. Die Auswertung gibt eine UnknownSet zurück. Die öffentliche API bietet derzeit keine Möglichkeit, den verbleibenden AST zu generieren.
  • Java:Unterstützt die partielle Auswertung über PartialVars, die an Program.eval() übergeben wird. Die Auswertung gibt ein CelUnknownSet zurück. Die öffentliche API bietet derzeit keine Möglichkeit, Residual-ASTs zu generieren.
  • Python / C:Keine native Unterstützung.

Asynchrone Auswertung

Bei der asynchronen Auswertung können CEL-Ausdrücke Funktionen aufrufen, die asynchron ausgeführt werden (z.B. RPCs oder Datenbankabfragen), und die Auswertung blockieren, bis die Ergebnisse verfügbar sind, ohne den Hauptausführungs-Thread zu blockieren.

  • Go:Unterstützt asynchrone Funktionsüberladungen über AsyncBinding und AsyncOp. Asynchrone Funktionen geben einen Go-Channel (<-chan ref.Val) zurück. Der Interpreter verwaltet die gleichzeitige Ausführung und Synchronisierung.
  • Java:Unterstützt die asynchrone Auswertung über CelAsyncRuntime und AsyncProgram. Dabei wird ListenableFuture verwendet, um ausstehende Werte darzustellen. Die Auswertung wird automatisch abgeschlossen, wenn Futures aufgelöst werden.
  • C++ / Python / C:Keine integrierte Unterstützung.

AST-Validatoren

Validatoren führen nach der Typüberprüfung eine statische Analyse des geprüften AST durch, um domänenspezifische Einschränkungen zu erzwingen, bevor das Programm ausgeführt wird.

  • Go:Unterstützt die ASTValidator-Schnittstelle. Zu den kanonischen Validatoren gehören cel.validator.duration, cel.validator.timestamp, cel.validator.matches (regulärer Ausdruck), cel.validator.homogeneous_literals und cel.validator.comprehension_nesting_limit.
  • C++:Unterstützt cel::Validator. Die kanonischen Validierungen umfassen AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidator und TimestampLiteralValidator.
  • Java:Unterstützt CelValidator und CelAstValidator. Zu den Canonical-Validatoren gehören AstDepthLimitValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, RegexLiteralValidator und TimestampLiteralValidator.
  • Python / C:Keine direkte Unterstützung.

AST-Optimierungstools

Optimierer schreiben den AST neu, um die Ausführungsleistung zu verbessern. Optimierungstools lassen sich in zwei Kategorien einteilen: statische und Laufzeit-Optimierungstools. C++, Java und Go unterstützen die Laufzeitoptimierung. CEL Java und Go unterstützen auch statische Optimierer. Typische Optimierungen sind das Zusammenfassen von Konstanten (die Vorab-Auswertung von Teilausdrücken mit konstanten Eingaben) und die Eliminierung gemeinsamer Teilausdrücke (Common Subexpression Elimination, CSE).

  • Go:Unterstützt das Zusammenfassen von AST während der Kompilierung/Planung.
  • C++:Unterstützt die konstante Faltung über die cel::extensions::EnableConstantFolding-Erweiterung zur Planungszeit.
  • Java:Unterstützt die CelOptimizer-Schnittstelle. Zu den kanonischen Optimierern gehören ConstantFoldingOptimizer (mit dem sich Short-Circuiting-Zweige durch Simulation der partiellen Auswertung zusammenfassen lassen), InliningOptimizer und SubexpressionOptimizer (CSE).
  • Python / C:Keine direkte Unterstützung.

CEL-Richtliniencompiler

CEL-Richtlinien sind ein YAML-basiertes Format zum Kombinieren mehrerer CEL-Ausdrücke mit Variablen, Match-Blöcken, bedingten Ausgaben und verschachtelten Regeln. Sie ist für komplexe Richtlinien-Engines (wie die Kubernetes-Zugangssteuerung) konzipiert, bei denen einzelne CEL-Ausdrücke unleserlich würden.

Der Policy Compiler kompiliert diese YAML-Richtlinien in einen einzelnen standardmäßigen CEL-AST. Das bedeutet, dass sie vollständig mit standardmäßigen CEL-Laufzeiten kompatibel sind und alle Leistungs- und Sicherheitsgarantien übernehmen.

  • Go:Wird über third_party/cel/go/policy unterstützt.
  • C++:Wird über third_party/cel/cpp/policy unterstützt.
  • Java:Wird über third_party/java/cel/policy unterstützt.
  • Python / C:Nicht direkt unterstützt.