Link Search Menu Expand Document Documentation Menu

正则表达式语法

正则表达式 (regex) 是一种使用特殊符号和运算符定义搜索模式的方法。这些模式允许您匹配字符串中的字符序列。

在 OpenSearch 中,您可以在以下查询类型中使用正则表达式:

OpenSearch 使用 Apache Lucene 正则表达式引擎,该引擎有其自身的语法和限制。它**不**使用 Perl 兼容正则表达式 (PCRE),因此一些熟悉的正则表达式功能可能行为不同或不受支持。

选择 regexp 和 query_string 查询

regexpquery_string 查询都支持正则表达式,但它们的行为不同,适用于不同的用例。

功能 regexp 查询 query_string 查询
模式匹配 正则表达式模式必须匹配整个字段值 正则表达式模式可以匹配字段的任何部分
flags 支持 flags 启用可选正则表达式运算符 不支持 flags
查询类型 词条级查询(不评分) 全文查询(评分和解析)
最佳用例 对关键词或精确字段进行严格模式匹配 在已分析字段中,使用支持正则表达式模式的灵活查询字符串进行搜索
复杂查询组合 仅限于正则表达式模式 支持 ANDOR、通配符、字段、提升以及其他功能。请参阅查询字符串查询

保留字符

Lucene 的正则表达式引擎支持所有 Unicode 字符。然而,以下字符被视为特殊运算符:

. ? + * | { } [ ] ( ) " \

根据启用的指定可选运算符flags,以下字符也可能被保留:

@ & ~ < >

要按字面意义匹配这些字符,请使用反斜杠 (\) 进行转义,或将整个字符串用双引号括起来。

  • \&:匹配字面上的 &
  • \\:匹配字面上的反斜杠 (\)
  • "hello@world":匹配完整字符串 hello@world

标准正则表达式运算符

Lucene 支持一组核心正则表达式运算符:

  • . – 匹配任意单个字符。**示例**:f.n 匹配后跟任意字符再跟 nf(例如,fanfin)。

  • ? – 匹配前一个字符零次或一次。**示例**:colou?r 匹配 colorcolour

  • + – 匹配前一个字符一次或多次。**示例**:go+ 匹配后跟一个或多个 oggogoogooo 等)。

  • * – 匹配前一个字符零次或多次。**示例**:lo*se 匹配后跟零个或多个 o 再跟 sellseloselooseloooose 等)。

  • {min,max} – 匹配特定范围的重复次数。如果省略 max,则匹配的字符数量没有上限。**示例**:x{3} 精确匹配 3 个 xxxx);x{2,4} 匹配 2 到 4 个 xxxxxxxxxx);x{3,} 匹配 3 个或更多 xxxxxxxxxxxxx 等)。

  • | – 用作逻辑 OR。**示例**:apple|orange 匹配 appleorange

  • ( ) – 将字符分组为子模式。**示例**:ab(cd)? 匹配 ababcd

  • [ ] – 匹配集合或范围中的一个字符。**示例**:[aeiou] 匹配任意元音。

    • - – 在方括号内提供时,表示一个范围,除非被转义或作为方括号内的第一个字符。**示例**:[a-z] 匹配任意小写字母;[-az] 匹配 -az[a\\-z] 匹配 a-z
    • ^ – 在方括号内提供时,用作逻辑 NOT,否定一个字符范围或集合中的任何字符。**示例**:[^az] 匹配除 az 之外的任何字符;[^a-z] 匹配除小写字母之外的任何字符;[^-az] 匹配除 -az 之外的任何字符;[^a\\-z] 匹配除 a-z 之外的任何字符。

可选运算符

您可以使用 flags 参数启用额外的正则表达式运算符。多个标志之间用 | 分隔。

以下是可用的标志:

  • ALL(默认)– 启用所有可选运算符。

  • COMPLEMENT – 启用 ~,它否定最短的后续表达式。**示例**:d~ef 匹配 dgfdxf,但不匹配 def

  • INTERSECTION – 启用 & 作为 AND 逻辑运算符。**示例**:ab.+&.+cd 匹配开头包含 ab 且结尾包含 cd 的字符串。

  • INTERVAL – 启用 <min-max> 语法以匹配数字范围。**示例**:id<10-12> 匹配 id10id11id12

  • 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]+"
      }
    }
  }
}

此查询匹配 error404error500

{
  "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"
      }
    }
  }
}

此查询匹配 error404error500

{
  "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"
      }
    }
  }
}

此查询匹配 error404error500

{
  "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"
        }
      }
    ]
  }
}

请注意,此查询还将匹配 xerror500error500xerrorxx500