弹性搜索的负向前瞻性正则表达式

Reg*_*res 4 regex negative-lookahead elasticsearch

我试图对弹性搜索查询做一个负面的预测,正则表达式是:

(?!.*charge)(?!.*encode)(?!.*relate).*night.*
Run Code Online (Sandbox Code Playgroud)

我要匹配的文字是:

在晚上住宿归还,仍然有建设问题.由于喷洒化学物质导致健康问题并导致眼睛受到刺激.

我没有得到任何幸运.有人能伸出援助之手吗?

ES查询:

  "query": {
    "filtered": {
      "query": {
        "bool": {
          "must_not": [
            {
              "regexp": {
                "message": {
                  "value": "(?!.*charge)(?!.*encode)(?!.*relate).*night.*",
                  "flags_value": 65535
                }
              }
            }
          ]
        }
      },
      "filter": {
        "match": {
          "resNb": {
            "query": "462031152161",
            "type": "boolean"
          }
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

Wik*_*żew 7

您可以使用以下两种方法之一解决问题:

"value": "~(charge|encode|relate)night~(charge|encode|relate)",
Run Code Online (Sandbox Code Playgroud)

要么

.*night.*&~(.*(charge|encode|relate).*)
Run Code Online (Sandbox Code Playgroud)

使用可选(因为它默认为ON )

"flags" : "ALL"
Run Code Online (Sandbox Code Playgroud)

它是如何工作的?

在常见的NFA正则表达式中,您通常使用负面外观来帮助限制更通用的模式(看起来像(?!...)或那些(?<!...)).但是,在ElasticSearch中,您需要使用特定的可选运算符.

~(波浪号)是补体被*使用之后它否定的原子.原子是组中的单个符号或一组子模式/替代.

请注意,默认情况下,所有ES模式都锚定在字符串的开头和结尾,您永远不需要在Perl-like和.NET以及其他NFA中使用^$通用.

从而,

  • ~(charge|encode|relate)- 匹配字符串开头以外的任何文本charge,encoderelate
  • night - 匹配单词 night
  • ~(charge|encode|relate) - 匹配除3个子字符串之外的任何文本,直到字符串结尾.

在像Perl这样的NFA正则表达式中,您可以使用调和的贪婪令牌来编写该模式:

/^(?:(?!charge|encode|relate).)*night(?:(?!charge|encode|relate).)*$/
Run Code Online (Sandbox Code Playgroud)

第二种模式比较棘手:常见的NFA正则表达式在匹配时通常不会从一个位置跳到另一个位置,因此常常使用锚定在文本开头的前瞻.在这里,使用INTERSECTION我们可以使用2个模式,其中一个匹配字符串,第二个也匹配字符串.

  • .*night.*-匹配整个线路(如.任何符号匹配,但换行,否则,使用(.|\n)*含)night
  • &-
  • ~(.*(charge|encode|relate).*)- 没有的行charge,encode以及其中的relate子串.

NFA Perl-like正则表达式看起来像

/^(?!.*(charge|encode|relate)).*night.*$/
Run Code Online (Sandbox Code Playgroud)