正则表达式语法
正则表达式 (regex) 是一种使用特殊符号和运算符定义搜索模式的方法。这些模式允许您匹配字符串中的字符序列。
在 OpenSearch 中,您可以在以下查询类型中使用正则表达式:
OpenSearch 使用 Apache Lucene 正则表达式引擎,该引擎有其自身的语法和限制。它**不**使用 Perl 兼容正则表达式 (PCRE),因此一些熟悉的正则表达式功能可能行为不同或不受支持。
选择 regexp 和 query_string 查询
regexp
和 query_string
查询都支持正则表达式,但它们的行为不同,适用于不同的用例。
功能 | regexp 查询 | query_string 查询 |
---|---|---|
模式匹配 | 正则表达式模式必须匹配整个字段值 | 正则表达式模式可以匹配字段的任何部分 |
flags 支持 | flags 启用可选正则表达式运算符 | 不支持 flags |
查询类型 | 词条级查询(不评分) | 全文查询(评分和解析) |
最佳用例 | 对关键词或精确字段进行严格模式匹配 | 在已分析字段中,使用支持正则表达式模式的灵活查询字符串进行搜索 |
复杂查询组合 | 仅限于正则表达式模式 | 支持 AND 、OR 、通配符、字段、提升以及其他功能。请参阅查询字符串查询。 |
保留字符
Lucene 的正则表达式引擎支持所有 Unicode 字符。然而,以下字符被视为特殊运算符:
. ? + * | { } [ ] ( ) " \
根据启用的指定可选运算符的 flags
,以下字符也可能被保留:
@ & ~ < >
要按字面意义匹配这些字符,请使用反斜杠 (\
) 进行转义,或将整个字符串用双引号括起来。
\&
:匹配字面上的&
\\
:匹配字面上的反斜杠 (\
)"hello@world"
:匹配完整字符串hello@world
标准正则表达式运算符
Lucene 支持一组核心正则表达式运算符:
-
.
– 匹配任意单个字符。**示例**:f.n
匹配后跟任意字符再跟n
的f
(例如,fan
或fin
)。 -
?
– 匹配前一个字符零次或一次。**示例**:colou?r
匹配color
和colour
。 -
+
– 匹配前一个字符一次或多次。**示例**:go+
匹配后跟一个或多个o
的g
(go
、goo
、gooo
等)。 -
*
– 匹配前一个字符零次或多次。**示例**:lo*se
匹配后跟零个或多个o
再跟se
的l
(lse
、lose
、loose
、loooose
等)。 -
{min,max}
– 匹配特定范围的重复次数。如果省略max
,则匹配的字符数量没有上限。**示例**:x{3}
精确匹配 3 个x
(xxx
);x{2,4}
匹配 2 到 4 个x
(xx
、xxx
或xxxx
);x{3,}
匹配 3 个或更多x
(xxx
、xxxx
、xxxxx
等)。 -
|
– 用作逻辑OR
。**示例**:apple|orange
匹配apple
或orange
。 -
( )
– 将字符分组为子模式。**示例**:ab(cd)?
匹配ab
和abcd
。 -
[ ]
– 匹配集合或范围中的一个字符。**示例**:[aeiou]
匹配任意元音。-
– 在方括号内提供时,表示一个范围,除非被转义或作为方括号内的第一个字符。**示例**:[a-z]
匹配任意小写字母;[-az]
匹配-
、a
或z
;[a\\-z]
匹配a
、-
或z
。^
– 在方括号内提供时,用作逻辑NOT
,否定一个字符范围或集合中的任何字符。**示例**:[^az]
匹配除a
或z
之外的任何字符;[^a-z]
匹配除小写字母之外的任何字符;[^-az]
匹配除-
、a
和z
之外的任何字符;[^a\\-z]
匹配除a
、-
和z
之外的任何字符。
可选运算符
您可以使用 flags
参数启用额外的正则表达式运算符。多个标志之间用 |
分隔。
以下是可用的标志:
-
ALL
(默认)– 启用所有可选运算符。 -
COMPLEMENT
– 启用~
,它否定最短的后续表达式。**示例**:d~ef
匹配dgf
、dxf
,但不匹配def
。 -
INTERSECTION
– 启用&
作为AND
逻辑运算符。**示例**:ab.+&.+cd
匹配开头包含ab
且结尾包含cd
的字符串。 -
INTERVAL
– 启用<min-max>
语法以匹配数字范围。**示例**:id<10-12>
匹配id10
、id11
和id12
。 -
ANYSTRING
– 启用@
以匹配任何字符串。您可以将其与~
和&
结合使用以进行排除。**示例**:@&.*error.*&.*[0-9]{3}.*
匹配同时包含单词“error”和三个数字序列的字符串。
不支持的功能
Lucene 引擎不支持以下常用的正则表达式锚点:
^
– 行首$
– 行尾
相反,您的模式必须匹配整个字符串才能产生匹配。
示例
要尝试正则表达式,请将以下文档索引到 logs
索引中:
PUT /logs/_doc/1
{
"message": "error404"
}
PUT /logs/_doc/2
{
"message": "error500"
}
PUT /logs/_doc/3
{
"message": "error1a"
}
示例:包含正则表达式的基本查询
以下 regexp
查询返回 message
字段的整个值与模式“error”后跟一个或多个数字匹配的文档。如果一个值仅包含该模式作为子字符串,则不匹配。
GET /logs/_search
{
"query": {
"regexp": {
"message": {
"value": "error[0-9]+"
}
}
}
}
此查询匹配 error404
和 error500
{
"took": 28,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "logs",
"_id": "1",
"_score": 1,
"_source": {
"message": "error404"
}
},
{
"_index": "logs",
"_id": "2",
"_score": 1,
"_source": {
"message": "error500"
}
}
]
}
}
示例:使用可选运算符
以下查询匹配 message
字段精确匹配以“error”开头,后跟 400 到 500(含)之间数字的字符串的文档。INTERVAL
标志启用数字范围的 <min-max>
语法。
GET /logs/_search
{
"query": {
"regexp": {
"message": {
"value": "error<400-500>",
"flags": "INTERVAL"
}
}
}
}
此查询匹配 error404
和 error500
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "logs",
"_id": "1",
"_score": 1,
"_source": {
"message": "error404"
}
},
{
"_index": "logs",
"_id": "2",
"_score": 1,
"_source": {
"message": "error500"
}
}
]
}
}
示例:使用 ANYSTRING
当启用 ANYSTRING
标志时,@
运算符匹配整个字符串。这在与交集 (&
) 结合使用时非常有用,因为它允许您构建在特定条件下匹配完整字符串的查询。
以下查询匹配同时包含单词“error”和三个数字序列的消息。使用 ANYSTRING
确保整个字段必须匹配这两个模式的交集。
GET /logs/_search
{
"query": {
"regexp": {
"message.keyword": {
"value": "@&.*error.*&.*[0-9]{3}.*",
"flags": "ANYSTRING|INTERSECTION"
}
}
}
}
此查询匹配 error404
和 error500
{
"took": 20,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "logs",
"_id": "1",
"_score": 1,
"_source": {
"message": "error404"
}
},
{
"_index": "logs",
"_id": "2",
"_score": 1,
"_source": {
"message": "error500"
}
}
]
}
}
请注意,此查询还将匹配 xerror500
、error500x
和 errorxx500
。