Biểu thức và hàm
Ở bất cứ đâu flow tính toán thay vì chỉ lưu — điều kiện If, cận của Loop, điều kiện trên cạnh, phép gán của Variable, đoạn chữ mà node Input Text gõ ra — vẫn là một ngôn ngữ nhỏ đó làm việc. Trang này là tham chiếu của nó.
Nó nhỏ có chủ đích. Không vòng lặp, không phép gán, không đường nào chạm tới ổ đĩa hay mạng. Một biểu thức đọc các giá trị và trả về một giá trị.
Tham chiếu tới một giá trị
{{gem_count}} biến gem_count
${gem_count} y hệt — cả hai cách viết đều được chấp nhận
vars.gem_count cũng biến đó, viết đầy đủ
result.output.text output của một node phía trên
Xem Biến để biết các giá trị đến từ đâu.
Toán tử
Ưu tiên cao trước — đúng thứ tự bộ phân tích áp dụng:
| Mức | Toán tử | Ghi chú |
|---|---|---|
| Truy cập | . [ ] | Thuộc tính và chỉ số: split(x, ",")[0] |
| Một ngôi | ! - | Phủ định, đảo dấu |
| Nhân chia | * / % | |
| Cộng trừ | + - | |
| So sánh | < <= > >= | |
| Bằng | == != | |
| Hợp nhất null | ?? | Vế trái, trừ khi nó là null |
| Và | && | Ngắn mạch |
| Hoặc | || | Ngắn mạch |
Ngoặc đơn nhóm như bạn nghĩ.
+ nối hai chuỗi, và cộng hai số. Nó từ chối cặp lệch kiểu — "5" + 1 báo lỗi chứ không đoán bạn muốn cái nào. Boolean không bao giờ là toán h ạng. Chia cho 0 báo lỗi.
Đây không phải thiếu sót. Nới lỏng + sẽ âm thầm đổi kết quả của mọi flow đã phát hành, nên chuyển kiểu là một hàm bạn nhìn thấy ngay trong biểu thức — number(), text(), int() — chứ không bao giờ là phép ép ngầm. Các dòng ý định của node Variable tự viết các lời gọi này giúp bạn: chọn "Cộng 1 vào bộ đếm" là có sẵn phép chuyển đúng mà không phải tự viết.
Các hàm
29 tên, liệt kê đủ bên dưới. Mọi hàm đều toàn phần — nó trả lời chứ không văng lỗi trước đầu vào lạ, ở bất cứ chỗ nào còn trả lời được — và mọi hàm trừ random đều tất định, nên một điều kiện phát lại y hệt.
Các vị từ văn bản quy null về chuỗi rỗng, nên contains(result.output.text, "Start") vẫn an toàn ngay cả khi node phát hiện phía trên không đọc được gì: bạn nhận false, không phải một lần chạy chết.
Kiểm tra văn bản
| Hàm | Trả về |
|---|---|
contains(text, part) | part có xuất hiện trong text không |
not_contains(text, part) | Ngược lại |
starts_with(text, part) | |
ends_with(text, part) | |
equals_ignore_case(a, b) | Bằng nhau, bỏ qua hoa thường |
is_empty(value) | Chuỗi rỗng, mảng rỗng, object rỗng, hoặc null |
is_not_empty(value) | Ngược lại |
regex_match(text, pattern) | Mẫu có được tìm thấy ở đâu đó trong text không |
Nhào nặn văn bản
| Hàm | Trả về |
|---|---|
lower(text) / upper(text) | Đổi hoa thường |
trim(text) | Bỏ khoảng trắng hai đầu |
concat(a, b, …) | Nối mọi tham số dạng chữ — phép nối lệch kiểu mà + từ chối |
replace(text, find, replacement) | Mọi lần xuất hiện, theo nghĩa đen. Không phải regex. find rỗng thì trả text nguyên vẹn |
split(text, separator) | Các phần, dạng mảng — lấy chỉ số: split(x, ",")[0]. Separator rỗng thì báo lỗi |
substring(text, start) | Từ start tới hết. start âm đếm ngược từ cuối |
substring(text, start, length) | Nhiều nhất length ký tự |
extract(text, pattern) | Nhóm bắt đầu tiên, hoặc cả khớp nếu mẫu không có nhóm — hoặc null khi không khớp gì |
extract(text, pattern, group) | Một nhóm cụ thể |
default(value, fallback) | fallback khi value là null hoặc rỗng |
len(value) / length(value) | Số ký tự, độ dài mảng, hay số khóa. null là 0 |
substring cắt vào cận thay vì văng lỗi. start vượt quá độ dài cho "". Một lần OCR đọc ra ngắn hơn thường lệ là chuyện cơm bữa, không phải lý do để giết một lần chạy.
extract trả null khi không khớp, và chính điều đó khiến nó ghép được: extract({{ocr}}, "[0-9]+") ?? "0".
default rộng hơn ??. ?? chỉ phủ null; default() phủ cả chuỗi rỗng — hình hài thường ngày của một lần đọc hụt.
Số
| Hàm | Trả về |
|---|---|
number(value) | Giá trị số — báo lỗi nếu không phải số |
number(value, fallback) | …hoặc lấy fallback thay vì báo lỗi |
text(value) | Giá trị dạng chữ |
is_number(value) | number() có thành công không |
int(value) | Cắt về phía 0 — int(-2.7) là -2 |
round(value) / round(value, digits) | Số 0.5 làm tròn ra xa 0 |
floor(value) / ceil(value) | |
abs(value) | |
min(a, b, …) / max(a, b, …) | |
clamp(value, low, high) | Kẹp trong cận. Báo lỗi nếu low > high |
random(low, high) | Một số nguyên trong [low, high], gồm cả hai đầu |
number() không đoán dấu phân cách"1,234" thật sự nhập nhằng — dấu phẩy nghĩa là hàng nghìn trong tiếng Anh và thập phân trong tiếng Việt. number() chỉ nhận số viết trơn. Muốn bỏ dấu phân cách thì tự replace(), để quyết định theo ngôn ngữ hiện ra trong flow chứ không bị flow giả định hộ.
round làm tròn đúng con số bạn viết. round(1.005, 2) là 1.01. Làm tròn trên xấp xỉ nhị phân sẽ ra 1.0 — bảo vệ được về lý thuyết, và không thể giải thích nổi trong một cuộc hỗ trợ.
random là hàm không tất định duy nhất, và đó chính là công dụng của nó: một flow luôn dùng đúng một cận thì lặp lại y hệt. Nó được bốc lại ở mỗi lần lượng giá — không có gì cache lại. Hai cận nhận theo thứ tự nào cũng được, và được làm tròn vào trong nên tham số lẻ không bao giờ nới rộng khoảng.
random(1, 100) <= 20 cứ năm lần chạy thì một
Cách viết cũ
Flow cũ và mọi thứ do trình dựng no-code biên dịch ra có thể dùng camelCase: notContains, startsWith, endsWith, equalsIgnoreCase, isEmpty, isNotEmpty. Chúng vẫn chạy và giống hệt bản snake_case. Cái gì viết mới thì dùng snake_case.
Mẫu thực dụng
Đọc một con số ra khỏi kết quả OCR nhiễu.
number(extract({{ocr_text}}, "[0-9]+") ?? "0")
extract moi chữ số ra khỏi "LEVEL 5", ?? cấp giá trị khi đọc hụt, và number biến nó thành thứ tính toán được. Không có fallback thì một lần đọc trống sẽ văng lỗi.
Lấy trường thứ n của bản ghi thứ n từ một chuỗi clipboard to.
split({{noidung}}, "\n")[{{i}} * 5 + 1]
Đây là lõi của ví dụ nhập liệu desktop: một cú Ctrl+C mang cả file về dạng chữ, và một bộ đếm Loop đi qua nó mỗi lần năm dòng.
Phần trăm không bao giờ vượt cận.
clamp(round({{done}} / {{total}} * 100), 0, 100)
Lỗi thường gặp
| Lỗi | Hậu quả | Cách sửa |
|---|---|---|
{{ocr}} + 1 trên một lần đọc OCR | Báo lỗi — chuỗi cộng số | number({{ocr}}, 0) + 1 |
number() trên "1,234" | Báo lỗi | number(replace({{x}}, ",", "")) |
Dùng replace() với regex | Không khớp gì — nó theo nghĩa đen | Dùng extract() cho mẫu |
Dùng ?? cho chuỗi rỗng | ?? chỉ phủ null | default(value, fallback) |
Tưởng extract trả "" | Nó trả null | Nối tiếp bằng ?? hoặc default() |
random trong điều kiện bạn muốn phát lại được | Nó được bốc lại mỗi lần lượng giá | Lưu vào biến trước |
Trang liên quan
- Biến, Input và Memory — các giá trị sống ở đâu
- If — node hay chứa biểu thức nhất
- Variable — phép gán, và các dòng ý định tự viết những lời gọi này
- Loop — bộ đếm và cận