Dokumentacja interfejsu Common Expression Language (CEL) API

Ten dokument służy jako ujednolicony dokument API języka Common Expression Language (CEL). Zawiera listę wszystkich makr, operatorów i funkcji standardowych, podając ich sygnatury, zachowania i stan obsługi w oficjalnych stosach CEL.

Więcej informacji o działaniu i specyfikacjach języka znajdziesz w definicji języka CEL.

Wersje stosu

Ten dokument referencyjny jest oparty na tych wersjach stosów CEL:

  • CEL Go: v0.29.2 (i nowsze)
  • CEL C++: v0.15.0
  • CEL Java: v0.13.1
  • CEL Python: v0.1.3
  • CEL C: wersja deweloperska (nieopublikowana)

Lustra GitHub

Oficjalne implementacje CEL są powielane w GitHub w organizacji cel-expr:


1. Podstawowe makra

Są to wbudowane makra, które są rozwijane w czasie kompilacji.

Makro Opis Go C++ Java Python C
has(container.field) Sprawdza, czy pole jest obecne w wiadomości lub czy klucz jest obecny na mapie.

Sygnatury:
has(container.field) -> bool

Przykłady:
has(request.auth.claims.email)
list.all(var, predicate) Sprawdza, czy wszystkie elementy na liście spełniają predykat.

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

Przykłady:
[1, 2, 3].all(x, x > 0) // true
¹
list.exists(var, predicate) Sprawdza, czy co najmniej 1 element na liście spełnia predykat.

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

Przykłady:
[1, 2, 3].exists(x, x > 2) // true
¹
list.exists_one(var, predicate) Sprawdza, czy dokładnie 1 element na liście spełnia predykat.

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

Przykłady:
[1, 2, 3].exists_one(x, x == 2) // true
¹
list.filter(var, predicate) Filtruje elementy listy zgodnie z predykatem.

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

Przykłady:
[1, 2, 3].filter(x, x > 1) // [2, 3]
¹
list.map(var, transform) Przekształca każdy element listy za pomocą wyrażenia.

Sygnatury:
list.map(var, transform) -> list

Przykłady:
[1, 2, 3].map(x, x * 2) // [2, 4, 6]
¹
list.map(var, filter, transform) Przekształca elementy listy, które spełniają predykat filtra.

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

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

¹ Obsługiwane w środowisku wykonawczym C, ponieważ makra są rozwijane do wyrażeń listowych podczas kompilacji przez kompilator hosta.


2. Operatorzy podstawowi

Operator Opis Go C++ Java Python C
Arytmetyka (+, -, *, /, %) standardowe operacje arytmetyczne, Negacja (-x) i tożsamość (+x). Konkatenacja list (list + list) jest obsługiwana w językach Go, C++, Java i Python.

Sygnatury:
T + T -> T
T - T -> T
T * T -> T
T / T -> T
T % T -> T
-T -> T
+T -> T
list + list -> list

Przykłady:
1 + 2 * 3 // 7
[1] + [2] // [1, 2]
²
Porównanie (==, !=, <, <=, >, >=) Standardowe porównanie. Porównania liczbowe są heterogeniczne (np. 1 == 1.0).

Sygnatury:
T == T -> bool
T != T -> bool
T < T -> bool
T <= T -> bool
T > T -> bool
T >= T -> bool

Przykłady:
x < 42.0
1 == 1.0 // true
Logiczne (!, &&, ||, ? :) Operatory logiczne NOT, AND, OR i Ternary Conditional. Używaj też skróconego obliczania wartości logicznej.

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

Przykłady:
x > 0 ? "positive" : "non-positive"
Indeksowanie ([]) Dostęp do elementu listy według indeksu lub klucza wyszukiwania na mapie.

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

Przykłady:
tags[0]
users['john']
Subskrypcja (in) Sprawdza, czy element znajduje się na liście lub czy klucz znajduje się na mapie.

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

Przykłady:
'admin' in roles

² Konkatenacja list (list + list) jest nieobsługiwana w środowisku wykonawczym języka C, ale inne operatory arytmetyczne są obsługiwane.


3. Główne funkcje

Funkcje ogólne i tekstowe

Funkcja Opis Go C++ Java Python C
size Zwraca rozmiar ciągu znaków, bajtów, listy lub mapy.

Sygnatury:
size(T) -> int (gdzie T to string, bytes, list lub map)<br /><br />**Examples:**<br />size("hello") // 5`
contains Zwraca wartość wskazującą, czy ciąg znaków zawiera podłańcuch.

Sygnatury:
string.contains(string) -> bool

Przykłady:
"hello".contains("ell") // true
startsWith Zwraca informację, czy ciąg znaków zaczyna się od prefiksu.

Sygnatury:
string.startsWith(string) -> bool

Przykłady:
"hello".startsWith("he") // true
endsWith Zwraca wartość wskazującą, czy ciąg znaków kończy się sufiksem.

Sygnatury:
string.endsWith(string) -> bool

Przykłady:
"hello".endsWith("lo") // true
matches Zwraca wartość wskazującą, czy ciąg znaków pasuje do wyrażenia regularnego RE2.

Sygnatury:
string.matches(string) -> bool

Przykłady:
"123".matches(r"^\d+$") // true

Funkcje selektora daty i godziny

Te funkcje wyodrębniają komponenty z google.protobuf.Timestamp lub google.protobuf.Duration.

Funkcja Opis Go C++ Java Python C
getFullYear Zwraca rok w formacie 4-cyfrowym.

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

Przykłady:
timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026
getMonth Zwraca miesiąc (0–11).

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

Przykłady:
timestamp("2026-07-23T00:00:00Z").getMonth() // 6
getDayOfMonth Zwraca dzień miesiąca (1–31).

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

Przykłady:
timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23
getDayOfWeek Zwraca dzień tygodnia (0 = niedziela).

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

Przykłady:
timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4
getDayOfYear Zwraca dzień roku (0–365).

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

Przykłady:
timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203
getHours Zwraca godziny (0–23).

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

Przykłady:
duration("1h30m").getHours() // 1
getMinutes Zwraca minuty (0–59).

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

Przykłady:
duration("1h30m").getMinutes() // 30
getSeconds Zwraca sekundy (0–59).

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

Przykłady:
duration("1h30m45s").getSeconds() // 45
getMilliseconds Zwraca milisekundy (0–999).

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

Przykłady:
duration("1.5s").getMilliseconds() // 500

Konwersje typów

Typ celu Opis Go C++ Java Python C
bool Konwertuje na wartość logiczną.

Sygnatury:
bool(bool) -> bool
bool(string) -> bool

Przykłady:
bool("true") // true
bytes Konwertuje na bajty.

Sygnatury:
bytes(bytes) -> bytes
bytes(string) -> bytes

Przykłady:
bytes("hello") // b"hello"
double Konwertuje na liczbę zmiennoprzecinkową podwójnej precyzji.

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

Przykłady:
double(1) // 1.0
duration Przekształca wartość na czas trwania.

Sygnatury:
duration(duration) -> duration
duration(string) -> duration

Przykłady:
duration("1.5s") // 1.5s duration
int Konwertuje na 64-bitową liczbę całkowitą ze znakiem.

Sygnatury:
int(int) -> int
int(uint) -> int
int(double) -> int (zaokrągla do zera)
int(string) -> int
int(timestamp) -> int (sekundy od początku epoki)

Przykłady:
int(1.5) // 1
string Konwertuje na ciąg znaków.

Sygnatury:
string(T) -> string (obsługuje bool, int, uint, double, bytes, timestamp, duration)<br /><br />**Examples:**<br />string(1.5) // "1.5"`
timestamp Konwertuje na sygnaturę czasową.

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

Przykłady:
timestamp("2026-07-23T00:00:00Z")
uint Konwertuje na 64-bitową liczbę całkowitą bez znaku.

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

Przykłady:
uint(1) // 1u
dyn Rzutuje wartość na typ dynamiczny w celu sprawdzenia typu.

Sygnatury:
dyn(T) -> dyn

Przykłady:
dyn([1, "two"])
type Zwraca typ wartości.

Sygnatury:
type(T) -> type

Przykłady:
type(1) // int

4. Rozszerzenia (biblioteki)

Biblioteka powiązań

Funkcja Opis Go C++ Java Python C
cel.bind Wiąże zmienną lokalną, aby uniknąć duplikowania oceny.

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

Przykłady:
cel.bind(x, a + b, x * x)
(v0.15.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)

Jak włączyć

Biblioteka koderów

Funkcja Opis Go C++ Java Python C
base64.encode Koduje bajty w ciąg znaków Base64.

Sygnatury:
base64.encode(bytes) -> string

Przykłady:
base64.encode(b"hello") // "aGVsbG8="
(wersja 0.6.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
base64.decode Dekoduje ciąg znaków base64 na bajty. Zwraca błąd w przypadku nieprawidłowych danych wejściowych.

Sygnatury:
base64.decode(string) -> bytes

Przykłady:
base64.decode("aGVsbG8=") // b"hello"
(wersja 0.6.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
json.encode Serializuje wartość CEL do ciągu JSON.

Sygnatury:
json.encode(dyn) -> string

Przykłady:
json.encode([1, 2]) // "[1,2]"
(v0.29.0)

Jak włączyć

Biblioteka matematyczna

Funkcja Opis Go C++ Java Python C
math.greatest Zwraca największą wartość z argumentów liczbowych (lub listy liczb).

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

Przykłady:
math.greatest(1, 3, 2) // 3
(v0.13.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
math.least Zwraca najmniejszą wartość z argumentów liczbowych (lub listy wartości liczbowych).

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

Przykłady:
math.least([1, 3, 2]) // 1
(v0.13.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
math.abs Wartość bezwzględna.

Sygnatury:
math.abs(T) -> T (obsługuje int, uint, double)<br /><br />**Examples:**<br />math.abs(-1) // 1`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.sqrt Pierwiastek kwadratowy.

Sygnatury:
math.sqrt(T) -> double (obsługuje int, uint, double)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0`
(wersja 0.25.1) (wersja 0.12.0) (wersja 0.11.0) (v0.1.1)
math.bitAnd Operator bitowy AND.

Sygnatury:
math.bitAnd(T, T) -> T (obsługuje int, uint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.bitOr Operacja bitowa LUB.

Sygnatury:
math.bitOr(T, T) -> T (obsługuje int, uint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.bitXor Bitowa operacja XOR.

Sygnatury:
math.bitXor(T, T) -> T (obsługuje int, uint)<br /><br />**Examples:**<br />math.bitXor(5, 3) // 6`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.bitNot Negacja bitowa.

Sygnatury:
math.bitNot(T) -> T (obsługuje int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.bitShiftLeft Przesunięcie bitowe w lewo.

Sygnatury:
math.bitShiftLeft(T, int) -> T (obsługuje int, uint)<br /><br />**Examples:**<br />math.bitShiftLeft(1, 2) // 4`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.bitShiftRight Przesunięcie bitowe w prawo.

Sygnatury:
math.bitShiftRight(T, int) -> T (obsługuje int, uint)<br /><br />**Examples:**<br />math.bitShiftRight(4, 2) // 1`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.ceil Zaokrąglanie w górę.

Sygnatury:
math.ceil(double) -> double

Przykłady:
math.ceil(1.2) // 2.0
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.floor Zaokrąglanie w dół.

Sygnatury:
math.floor(double) -> double

Przykłady:
math.floor(1.8) // 1.0
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.round Zaokrąglanie do najbliższej liczby całkowitej.

Sygnatury:
math.round(double) -> double

Przykłady:
math.round(1.5) // 2.0
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.trunc Zaokrąglanie przez obcięcie (w kierunku zera).

Sygnatury:
math.trunc(double) -> double

Przykłady:
math.trunc(-1.8) // -1.0
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.isInf Sprawdza, czy liczba zmiennoprzecinkowa jest dodatnią lub ujemną nieskończonością.

Sygnatury:
math.isInf(double) -> bool

Przykłady:
math.isInf(1.0/0.0) // true
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.isNaN Sprawdza, czy liczba zmiennoprzecinkowa jest wartością NaN.

Sygnatury:
math.isNaN(double) -> bool

Przykłady:
math.isNaN(0.0/0.0) // true
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.isFinite Sprawdza, czy liczba zmiennoprzecinkowa jest skończona.

Sygnatury:
math.isFinite(double) -> bool

Przykłady:
math.isFinite(1.2) // true
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
math.sign Zwraca znak wartości (-1, 0 lub 1).

Sygnatury:
math.sign(T) -> T (obsługuje int, uint, double)<br /><br />**Examples:**<br />math.sign(-42) // -1`
(wersja 0.21.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)

Jak włączyć

Biblioteka Protos

Funkcja Opis Go C++ Java Python C
proto.getExt Pobiera pole rozszerzenia proto2 lub wartość domyślną, jeśli nie jest ustawione.

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

Przykłady:
proto.getExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
proto.hasExt Sprawdza, czy pole rozszerzenia proto2 jest ustawione.

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

Przykłady:
proto.hasExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)

Jak włączyć

Biblioteka list

Funkcja Opis Go C++ Java Python C
distinct Zwraca różne elementy.

Sygnatury:
list.distinct() -> list

Przykłady:
[1, 2, 2].distinct() // [1, 2]
(wersja 0.22.0) (wersja 0.11.0) (wersja 0.11.0) (v0.1.1)
flatten Spłaszcza zagnieżdżone listy.

Sygnatury:
list.flatten([depth]) -> list

Przykłady:
[[1], [2, 3]].flatten() // [1, 2, 3]
(wersja 0.22.0) (wersja 0.11.0) (wersja 0.7.1) (v0.1.1)
lists.range Zwraca listę liczb całkowitych [0, ..., n-1].

Sygnatury:
lists.range(int) -> list(int)

Przykłady:
lists.range(3) // [0, 1, 2]
(wersja 0.22.0) (wersja 0.11.0) (wersja 0.10.1) (v0.1.1)
reverse Odwraca listę.

Sygnatury:
list.reverse() -> list

Przykłady:
[1, 2].reverse() // [2, 1]
(wersja 0.22.0) (wersja 0.11.0) (wersja 0.11.0) (v0.1.1)
slice Zwraca podlistę (wartość początkowa jest traktowana włącznie, a wartość końcowa wyłącznie).

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

Przykłady:
[1, 2, 3].slice(1, 3) // [2, 3]
(wersja 0.17.0) (wersja 0.11.0) (wersja 0.11.0) (v0.1.1)
sort Sortuje listę porównywalnych elementów.

Sygnatury:
list.sort() -> list

Przykłady:
[3, 1, 2].sort() // [1, 2, 3]
(wersja 0.22.0) (wersja 0.11.0) (wersja 0.11.0) (v0.1.1)
sortBy Sortuje listę według klucza obliczonego na podstawie wyrażenia.

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

Przykłady:
[{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}]
(wersja 0.22.0) (wersja 0.11.0) (wersja 0.11.0) (v0.1.1)
first Zwraca pierwszy element jako opcjonalny. Wymaga rozszerzenia opcjonalnego.

Podpisy:
list.first() -> optional

Przykłady:
[1, 2].first() // optional(1)
(v0.23.0) (v0.15.0) (wersja 0.11.0) (v0.1.2)
last Zwraca ostatni element jako opcjonalny. Wymaga rozszerzenia opcjonalnego.

Podpisy:
list.last() -> optional

Przykłady:
[1, 2].last() // optional(2)
(v0.23.0) (v0.15.0) (wersja 0.11.0) (v0.1.2)

Jak włączyć

Biblioteka zestawów

Funkcja Opis Go C++ Java Python C
sets.contains Sprawdza, czy lista1 zawiera wszystkie elementy listy2.

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

Przykłady:
sets.contains([1, 2], [1]) // true
(v0.15.0) (wersja 0.10.0) (wersja 0.6.0) (v0.1.1)
sets.equivalent Sprawdza, czy listy są równoważne (zawierają te same unikalne elementy).

Sygnatury:
sets.equivalent(list1, list2) -> bool

Przykłady:
sets.equivalent([1, 2], [2, 1, 1]) // true
(v0.15.0) (wersja 0.10.0) (wersja 0.6.0) (v0.1.1)
sets.intersects Sprawdza, czy listy mają co najmniej 1 element wspólny.

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

Przykłady:
sets.intersects([1, 2], [2, 3]) // true
(v0.15.0) (wersja 0.10.0) (wersja 0.6.0) (v0.1.1)

Jak włączyć

Biblioteka ciągów znaków

Funkcja Opis Go C++ Java Python C
charAt Zwraca znak na pozycji.

Sygnatury:
string.charAt(int) -> string

Przykłady:
"hello".charAt(1) // "e"
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
indexOf Zwraca indeks pierwszego wystąpienia podciągu lub -1.

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

Przykłady:
"hello".indexOf("l") // 2
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
lastIndexOf Zwraca indeks ostatniego wystąpienia podciągu lub -1.

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

Przykłady:
"hello".lastIndexOf("l") // 3
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
join Łączy ciągi znaków.

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

Przykłady:
["a", "b"].join("-") // "a-b"
(wersja 0.10.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
split Dzieli ciąg znaków według separatora.

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

Przykłady:
"a-b".split("-") // ["a", "b"]
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
substring Zwraca podciąg (wartość początkowa jest wliczana, a końcowa nie).

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

Przykłady:
"hello".substring(1, 3) // "el"
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
trim Usuwa znaki odstępu Unicode.

Podpisy:
string.trim() -> string

Przykłady:
" hello ".trim() // "hello"
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
replace Zastępuje wystąpienia argumentu old argumentem new.

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

Przykłady:
"hello".replace("l", "w") // "hewwo"
(wersja 0.4.0) (wersja 0.10.0) (wersja 0.2.0) (v0.1.1)
reverse Odwraca punkty kodowe Unicode.

Sygnatury:
string.reverse() -> string

Przykłady:
"abc".reverse() // "cba"
(wersja 0.18.0) (wersja 0.14.0) (v0.13.0) (v0.1.1)
lowerAscii Konwertuje znaki ASCII na małe litery.

Sygnatury:
string.lowerAscii() -> string

Przykłady:
"Hello".lowerAscii() // "hello"
(wersja 0.6.0) (wersja 0.11.0) (wersja 0.2.0) (v0.1.1)
upperAscii Zmienia znaki ASCII na wielkie litery.

Sygnatury:
string.upperAscii() -> string

Przykłady:
"Hello".upperAscii() // "HELLO"
(wersja 0.6.0) (wersja 0.11.0) (wersja 0.2.0) (v0.1.1)
quote Escapes string for safe printing.

Signatures:
strings.quote(string) -> string

Examples:
strings.quote("a\tb") // "\"a\\tb\""
(wersja 0.14.0) (wersja 0.14.0) (v0.13.0) (v0.1.1)

Jak włączyć

Biblioteka wyrażeń regularnych

Funkcja Opis Go C++ Java Python C
regex.replace Zastępuje dopasowania ciągiem znaków (obsługuje odwołania wsteczne).

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

Przykłady:
regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123"
(wersja 0.25.1) (v0.13.0) (wersja 0.10.1) (v0.1.1)
regex.extract Zwraca pierwsze dopasowanie wzorca (musi zawierać jedną grupę przechwytywania).

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

Przykłady:
regex.extract("a123b", r"(\d+)") // optional("123")
(wersja 0.25.1) (v0.13.0) (wersja 0.10.1) (v0.1.1)
regex.extractAll Zwraca wszystkie dopasowania wzorca (musi zawierać jedną grupę przechwytywania).

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

Przykłady:
regex.extractAll("a1b2", r"(\d+)") // ["1", "2"]
(wersja 0.25.1) (v0.13.0) (wersja 0.10.1) (v0.1.1)

Jak włączyć

Listy składane z 2 zmiennymi

Makro Opis Go C++ Java Python C
all Skracanie logicznego operatora AND w przypadku klucza/indeksu i wartości.

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

Przykłady:
[1, 2].all(i, v, v > 0) // true
(wersja 0.22.0) (wersja 0.14.0) (wersja 0.11.0) (v0.1.1)
exists Skracanie logicznego operatora LUB w przypadku klucza/indeksu i wartości.

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

Przykłady:
[1, 2].exists(i, v, v == 2) // true
(wersja 0.22.0) (wersja 0.14.0) (wersja 0.11.0) (v0.1.1)
existsOne Sprawdza, czy dokładnie jedna para spełnia predykat.

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

Przykłady:
[1, 2].existsOne(i, v, v == 2) // true
(wersja 0.22.0) (wersja 0.14.0) (wersja 0.11.0) (v0.1.1)
transformList Przekształca/filtruje listę/mapę w listę.

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

Przykłady:
[1, 2].transformList(i, v, v * 2) // [2, 4]
(wersja 0.22.0) (wersja 0.14.0) (wersja 0.11.0) (v0.1.1)
transformMap Przekształca wartości listy lub mapy w mapę (klucze pozostają stałe).

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

Przykłady:
[1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4}
(wersja 0.22.0) (wersja 0.14.0) (wersja 0.11.0) (v0.1.1)
transformMapEntry Przekształca się w mapę.

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

Przykłady:
[1, 2].transformMapEntry(i, v, {string(v): v * 2}) // {"1": 2, "2": 4}
(wersja 0.22.0) (wersja 0.14.0) (wersja 0.11.0) (v0.1.1)

Jak włączyć

Biblioteka typów natywnych

Funkcja Opis Go C++ Java Python C
Struktury natywne Rejestrowanie i tworzenie instancji natywnych typów hosta (struktur Go lub obiektów POJO w Javie) w CEL.

Przykłady:
Account{id: 123} (obiekt POJO w Javie utworzony w CEL)
(v0.13.0) (v0.13.0)

Jak włączyć

  • Przekaż: przekaż ext.NativeTypes(...) (podając typy odbicia) do cel.NewEnv().
  • C++: nieobsługiwane.
  • Java: dodaj CelExtensions.nativeTypes() (zawierający klasy Java) do konstruktorów CelCompilerCelRuntime.
  • Python: nieobsługiwany.

Biblioteka sieciowa

Biblioteka Network udostępnia funkcje do analizowania, weryfikowania i manipulowania adresami IP oraz blokami CIDR.

Funkcja Opis Go C++ Java Python C
ip Analizuje ciąg znaków i wyodrębnia z niego adres IP lub adres IP z bloku CIDR.

Sygnatury:
ip(string) -> IP
CIDR.ip() -> IP

Przykłady:
ip("192.168.0.1")
cidr("192.168.0.0/24").ip()
(v0.29.0)
isIP Sprawdza, czy ciąg znaków jest prawidłowym adresem IP.

Sygnatury:
isIP(string) -> bool

Przykłady:
isIP("192.168.0.1") // true
(v0.29.0)
ip.isCanonical Sprawdza, czy ciąg tekstowy adresu IP jest w formacie kanonicznym.

Sygnatury:
ip.isCanonical(string) -> bool

Przykłady:
ip.isCanonical("192.168.0.1") // true
(v0.29.0)
cidr Analizuje ciąg znaków i przekształca go w blok CIDR.

Sygnatury:
cidr(string) -> CIDR

Przykłady:
cidr("192.168.0.0/24")
(v0.29.0)
isCIDR Sprawdza, czy ciąg znaków jest prawidłowym blokiem CIDR.

Sygnatury:
isCIDR(string) -> bool

Przykłady:
isCIDR("192.168.0.0/24") // true
(v0.29.0)
containsIP Sprawdza, czy blok CIDR zawiera adres IP.

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

Przykłady:
cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true
(v0.29.0)
containsCIDR Sprawdza, czy blok CIDR zawiera inny blok CIDR.

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

Przykłady:
cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true
(v0.29.0)
family Zwraca rodzinę adresów IP (4 – IPv4, 6 – IPv6).

Sygnatury:
IP.family() -> int

Przykłady:
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast Sprawdza, czy adres IP jest globalnym adresem typu unicast.

Sygnatury:
IP.isGlobalUnicast() -> bool

Przykłady:
ip("192.168.0.1").isGlobalUnicast() // true
(v0.29.0)
isLinkLocalMulticast Sprawdza, czy adres IP jest adresem rozgłoszeniowym połączenia lokalnego.

Sygnatury:
IP.isLinkLocalMulticast() -> bool

Przykłady:
ip("224.0.0.1").isLinkLocalMulticast() // true
(v0.29.0)
isLinkLocalUnicast Sprawdza, czy adres IP jest adresem typu unicast połączenia lokalnego.

Sygnatury:
IP.isLinkLocalUnicast() -> bool

Przykłady:
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback Sprawdza, czy adres IP jest adresem zwrotnym.

Sygnatury:
IP.isLoopback() -> bool

Przykłady:
ip("127.0.0.1").isLoopback() // true
(v0.29.0)
isMask Sprawdza, czy CIDR jest prawidłową maską podsieci.

Sygnatury:
CIDR.isMask() -> bool

Przykłady:
cidr("255.255.255.0/24").isMask() // true
(v0.29.0)
isUnspecified Sprawdza, czy adres IP jest nieokreślonym adresem (np. 0.0.0.0).

Sygnatury:
IP.isUnspecified() -> bool

Przykłady:
ip("0.0.0.0").isUnspecified() // true
(v0.29.0)
masked Zwraca zamaskowany blok CIDR.

Sygnatury:
CIDR.masked() -> CIDR

Przykłady:
cidr("192.168.0.1/24").masked() // 192.168.0.0/24
(v0.29.0)
prefixLength Zwraca długość prefiksu bloku CIDR.

Sygnatury:
CIDR.prefixLength() -> int

Przykłady:
cidr("192.168.0.0/24").prefixLength() // 24
(v0.29.0)
string Konwertuje adres IP lub CIDR na ciąg znaków.

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

Przykłady:
string(ip("192.168.0.1")) // "192.168.0.1"
(v0.29.0)

Jak włączyć

  • Podaj: podaj ext.Network() do cel.NewEnv().
  • C++: nieobsługiwane.
  • Java: nieobsługiwane.
  • Python: nieobsługiwany.

5. Funkcje zaawansowane

Podsumowanie funkcji zaawansowanych

Funkcja Opis Go C++ Java Python C
Ocena częściowa Obliczanie z brakującymi danymi wejściowymi; zwraca nieznane wartości lub uproszczone wyrażenie. ³
Ocena asynchroniczna Równoległe wykonywanie funkcji rozszerzenia bez blokowania.
Walidatory AST Kontrole analizy statycznej na sprawdzonym AST po sprawdzeniu typu.
Optymalizatory AST Przepisywanie AST (stałe składanie, wstawianie, CSE) w celu zwiększenia wydajności.
Kompilator zasad CEL Kompiluje struktury zasad oparte na YAML do standardowych drzew AST CEL.

³ Go obsługuje generowanie pozostałego drzewa AST (przyciętego drzewa AST). ⁴ C++ i Java obsługują zwracanie UnknownSet / CelUnknownSet w czasie działania, ale nie udostępniają publicznych interfejsów API do generowania pozostałego drzewa składni abstrakcyjnej. ⁵ Go używa kanałów AsyncBinding / AsyncOp zwracających. ⁶ Java używa CelAsyncRuntime, zwracając ListenableFuture.

Częściowa ocena (nieznane)

Częściowa ocena umożliwia ocenę wyrażenia, gdy znany jest tylko podzbiór zmiennych wejściowych (argumentów). Zamiast błędu ocena zwraca wynik wskazujący, czego brakuje, lub uproszczone wyrażenie.

  • Go: pełna obsługa. Umożliwia zdefiniowanie PartialActivation ze wzorcami nieznanych atrybutów. Ocena zwraca wartość types.Unknown. Go obsługuje generowanie pozostałego drzewa składni abstrakcyjnej (Env.ResidualAst), które jest przyciętym, uproszczonym drzewem składni abstrakcyjnej zawierającym tylko części wyrażenia, których nie można było obliczyć.
  • C++: obsługuje wartości Unknown. Nieznane wzorce atrybutów są konfigurowane za pomocą Activation::set_unknown_attribute_patterns. Funkcja Evaluation zwraca wartość UnknownSet. Publiczny interfejs API nie udostępnia obecnie generowania pozostałego AST.
  • Java: obsługuje częściową ocenę za pomocą funkcji PartialVars przekazywanej do Program.eval(). Ocena zwraca wartość CelUnknownSet. Publiczny interfejs API nie udostępnia obecnie generowania AST resztowego.
  • Python / C: brak natywnej obsługi.

Ocena asynchroniczna

Asynchroniczna ocena umożliwia wyrażeniom CEL wywoływanie funkcji, które wykonują się asynchronicznie (np. wykonują wywołania RPC lub zapytania do bazy danych) i blokują ocenę do momentu uzyskania wyników, nie blokując głównego wątku wykonania.

  • Go: obsługuje przeciążenia funkcji asynchronicznych za pomocą AsyncBindingAsyncOp. Funkcje asynchroniczne zwracają kanał Go (<-chan ref.Val), a interpreter zarządza współbieżnym wykonywaniem i synchronizacją.
  • Java: obsługuje ocenę asynchroniczną za pomocą CelAsyncRuntimeAsyncProgram. Używa symbolu ListenableFuture do reprezentowania wartości oczekujących i automatycznie doprowadza ocenę do końca, gdy przyszłe wartości zostaną rozwiązane.
  • C++ / Python / C: brak wbudowanej obsługi.

Walidatory AST

Po sprawdzeniu typów walidatory przeprowadzają statyczną analizę sprawdzonego drzewa AST, aby przed wykonaniem programu wymusić ograniczenia specyficzne dla domeny.

  • Go: obsługuje interfejs ASTValidator. Weryfikatory kanoniczne to cel.validator.duration, cel.validator.timestamp, cel.validator.matches (wyrażenie regularne), cel.validator.homogeneous_literalscel.validator.comprehension_nesting_limit.
  • C++: obsługuje cel::Validator. Weryfikacje kanoniczne obejmują AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidatorTimestampLiteralValidator.
  • Java: obsługuje CelValidatorCelAstValidator. Weryfikatory kanoniczne to AstDepthLimitValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, RegexLiteralValidatorTimestampLiteralValidator.
  • Python / C: brak bezpośredniej obsługi.

Optymalizatory AST

Optymalizatory przepisują AST, aby zwiększyć wydajność wykonywania. Optymalizatory dzielą się na 2 kategorie: statyczne i działające w czasie wykonywania. Języki C++, Java i Go obsługują optymalizację w czasie działania. CEL Java i Go obsługują też optymalizatory statyczne. Typowe optymalizacje to m.in. zwijanie stałych (wstępne obliczanie podwyrażeń ze stałymi danymi wejściowymi) i eliminacja wspólnych podwyrażeń (CSE).

  • Go: obsługuje składanie AST podczas kompilacji lub planowania.
  • C++: obsługuje składanie stałych za pomocą rozszerzenia cel::extensions::EnableConstantFolding w momencie planowania.
  • Java: obsługuje interfejs CelOptimizer. Optymalizatory kanoniczne obejmują ConstantFoldingOptimizer (który może zwijać gałęzie zwarcia przez symulowanie częściowej oceny), InliningOptimizerSubexpressionOptimizer (CSE).
  • Python / C: brak bezpośredniej obsługi.

Kompilator zasad CEL

Zasady CEL to format oparty na YAML, który umożliwia łączenie wielu wyrażeń CEL z zmiennymi, blokami dopasowania, danymi wyjściowymi warunkowymi i zagnieżdżonymi regułami. Jest on przeznaczony do złożonych silników zasad (takich jak kontrola dostępu Kubernetes), w których pojedyncze wyrażenia CEL stają się nieczytelne.

Kompilator zasad kompiluje te zasady YAML do pojedynczego standardowego drzewa składni abstrakcyjnej CEL, co oznacza, że są one w pełni zgodne ze standardowymi środowiskami wykonawczymi CEL i dziedziczą wszystkie gwarancje wydajności i bezpieczeństwa.

  • Go: obsługiwany za pomocą third_party/cel/go/policy.
  • C++: obsługiwany przez third_party/cel/cpp/policy.
  • Java: obsługiwany za pomocą third_party/java/cel/policy.
  • Python / C: nie jest obsługiwany bezpośrednio.