Cloudflare Rules language 支持比较运算符与逻辑运算符:
分组符号 允许你组织表达式、强制优先级以及嵌套表达式。
当 HTTP 请求中的值与表达式中定义的值匹配时,比较运算符返回 true。
使用比较运算符的一般模式为:
<field> <comparison_operator> <value>Rules language 支持以下比较运算符:
| 名称 | 运算符记法 | 支持的数据类型 | ||||
|---|---|---|---|---|---|---|
| English | C-like | String1 | IP | Number | 示例(运算符加粗) | |
| 等于 | eq | == | ✅ | ✅ | ✅ | http.request.uri.path eq "/articles/2008/" |
| 不等于 | ne | != | ✅ | ✅ | ✅ | ip.src ne 203.0.113.0 |
| 小于 | lt | < | ✅ | ❌ | ✅ | cf.waf.score lt 10 |
| 小于或等于 | le | <= | ✅ | ❌ | ✅ | cf.waf.score le 20 |
| 大于 | gt | > | ✅ | ❌ | ✅ | cf.waf.score gt 25 |
| 大于或等于 | ge | >= | ✅ | ❌ | ✅ | cf.waf.score ge 60 |
| 包含 | contains | ✅ | ❌ | ❌ | http.request.uri.path contains "/articles/" | |
| 通配符 (不区分大小写) | wildcard | ✅ | ❌ | ❌ | http.request.uri.path wildcard "/articles/*" | |
| 严格通配符 (区分大小写) | strict wildcard | ✅ | ❌ | ❌ | http.request.uri.path strict wildcard "/AdminTeam/*" | |
| 匹配 正则表达式2 | matches | ~ | ✅ | ❌ | ❌ | http.request.uri.path matches "^/articles/200[7-8]/$" |
| 属于值集 / 列表3 | in | ✅ | ✅ | ✅ | ip.src in { 203.0.113.0 203.0.113.1 }ip.src.asnum in $<LIST> | |
1 除非明确声明为不区分大小写(例如 wildcard 运算符),所有字符串运算符均区分大小写。
2 使用 matches 运算符需要 Cloudflare Business 或 Enterprise 计划。
3 目前,并非所有 Cloudflare 产品都在其表达式中支持列表。有关列表的更多信息,请参阅 Inline lists 与 Lists。
根据具体字段与规则类型,Cloudflare 仪表板可能显示以下其他运算符:
-
starts with(对应
starts_with()函数):当字符串以给定子字符串开头时返回true,否则返回false。 -
ends with(对应
ends_with()函数):当字符串以给定子字符串结尾时返回true,否则返回false。 -
is in list(对应
<FIELD> in $<LIST_NAME>):当字段值存在于指定列表中时返回true,否则返回false。更多信息请参阅 Use lists in expressions。 -
is not in list(对应
not <FIELD> in $<LIST_NAME>):当字段值不存在于指定列表中时返回true,否则返回false。更多信息请参阅 Use lists in expressions。
规则表达式中的字符串比较区分大小写。为应对表达式中字符串大小写的可能变化,你可以使用 lower() 函数,并将结果与小写字符串进行比较,如下例所示:
lower(http.request.uri.path) contains "/wp-login.php"通配符匹配仅由 wildcard 与 strict wildcard 运算符支持,正则表达式匹配仅由 matches 运算符支持。
wildcard 运算符在字段值与包含零个或多个 * 元字符的字面字符串之间执行不区分大小写的匹配。每个 * 元字符表示零个或多个字符。strict wildcard 运算符执行类似匹配,但区分大小写。
使用 wildcard/strict wildcard 运算符时,整个字段值必须与带通配符的字面字符串(运算符后的字面量)匹配。
# The following expression:
http.request.full_uri wildcard "http*://example.com/a/*"
# Would match the following URIs:
# - https://example.com/a/ (the '*' matches zero characters)
# - http://example.com/a/
# - https://example.com/a/page.html
# - https://example.com/a/sub/folder/?name=value
# Would NOT match the following URIs:
# - https://example.com/ab/
# - https://example.com/b/page.html
# - https://sub.example.com/a/Example B
# The following expression:
http.request.full_uri wildcard "*.example.com/*/page.html"
# Would match the following URIs:
# - http://sub.example.com/folder/page.html
# - https://admin.example.com/team/page.html
# - https://admin.example.com/team/subteam/page.html
# Would NOT match the following URIs:
# - https://example.com/ab/page.html ('*.example.com' matches only subdomains)
# - https://sub.example.com/folder2/page.html?s=value (http.request.full_uri includes the query string and its full value does not match)
# - https://sub.example.com/a/ ('page.html' is missing)斜杠(/)在通配符匹配中没有特殊含义。在此示例中,表达式 http.request.full_uri wildcard "*.example.com/*/page.html" 中的第二个 * 元字符匹配了 folder、team 与 team/subteam。
Example C
# The following expression:
http.request.full_uri wildcard "*.example.com/*" or http.request.full_uri wildcard "http*://example.com/*"
# Would match the following URIs:
# - https://example.com/folder/list.htm
# - https://admin.example.com/folder/team/app1/
# - https://admin.example.com/folder/team/app1/?s=foobarwildcard 运算符使用的匹配算法不区分大小写。要执行区分大小写的通配符匹配,请使用 strict wildcard 运算符。
要在带通配符的字面字符串中输入字面 * 字符,必须使用 \* 转义。此外,还必须使用 \\ 转义 \。通配符字面字符串中连续两个未转义的 * 字符(**)被视为无效且不能使用。如果需要执行字符转义,建议使用 raw string syntax 指定带通配符的字面字符串。
Business 与 Enterprise 计划客户可使用 matches 运算符。正则表达式匹配使用 Rust 正则表达式引擎执行。
如果使用正则表达式,可使用 Regular Expressions 101 ↗ 或 Rustexp ↗ 等工具进行测试。
有关正则表达式的更多信息,请参阅 String values and regular expressions。
逻辑运算符将两个或多个表达式组合成单个复合表达式。复合表达式的一般语法为:
<expression> <logical_operator> <expression>每个逻辑运算符都有一个优先级顺序。优先级顺序(以及分组符号)决定 Cloudflare 在表达式中对逻辑运算符求值的顺序。not 运算符在优先级顺序中排名第一。
| 名称 | English 记法 | C-like 记法 | 示例 | 优先级顺序 |
|---|---|---|---|---|
| 逻辑 NOT | not | ! | not ( http.host eq "www.cloudflare.com" and ip.src in {203.0.113.0/24} ) | 1 |
| 逻辑 AND | and | && | http.host eq "www.cloudflare.com" and ip.src in {203.0.113.0/24} | 2 |
| 逻辑 XOR (异或) | xor | ^^ | http.host eq "www.cloudflare.com" xor ip.src in {203.0.113.0/24} | 3 |
| 逻辑 OR | or | || | http.host eq "www.cloudflare.com" or ip.src in 203.0.113.0/24 | 4 |
编写复合表达式时,了解逻辑运算符的优先级非常重要,以便表达式按预期求值。
例如,考虑以下使用 and 与 or 运算符的通用表达式:
Expression1 and Expression2 or Expression3如果这些运算符没有优先级顺序,则不清楚以下两种解释中哪一种正确:
- 当 Expression 1 与 Expression 2 均为 true 或 Expression 3 为 true 时匹配。
- 当 Expression 1 为 true 且 Expression 2 或 Expression 3 任一为 true 时匹配。
由于逻辑 and 运算符的优先级高于逻辑 or,必须先对 and 运算符求值。解释 1 是正确的。
为避免使用逻辑运算符时产生歧义,请使用分组符号,使求值顺序明确。
Rules language 支持使用圆括号((、))作为分组符号。分组符号允许你组织表达式、强制优先级以及嵌套表达式。
只有 Expression Editor 与 Cloudflare API 支持分组符号。Expression Builder 不支持。
使用圆括号显式将应一起求值的表达式分组。在此示例中,圆括号不改变表达式的求值结果,但明确指出应先对哪些逻辑运算符求值。
(Expression1 and Expression2) or Expression3由于分组符号非常明确,在使用它们编写复合表达式时更不容易出错。
分组符号是对复合表达式中已分组元素强制优先级的强大工具。在此示例中,圆括号强制逻辑 or 运算符在逻辑 and 之前求值:
Expression1 and (Expression2 or Expression3)没有圆括号时,逻辑 and 运算符将优先。
你可以将由圆括号分组的表达式嵌套在其他分组内,以创建非常精确、复杂的表达式,例如这个用于阻止访问某个域名的规则示例:
(
(http.host eq "api.example.com" and http.request.uri.path eq "/api/v2/auth") or
(http.host matches "^(www|store|blog)\.example\.com" and http.request.uri.path contains "wp-login.php") or
ip.src.country in {"CN" "TH" "US" "ID" "KR" "MY" "IT" "SG" "GB"} or ip.src.asnum in {12345 54321 11111}
) and not ip.src in {11.22.33.0/24}请注意,在评估逻辑运算符的优先级时,引号分隔的字符串内的圆括号会被忽略,例如从上例中提取的以下正则表达式:
"^(www|store|blog)\.example\.com"