当前位置: 首页 > 面试题库 >

在Elasticsearch上使用负前瞻正则表达式

锺离宸
2023-03-14
问题内容

我正在尝试对Elasticsearch查询进行否定前瞻,正则表达式为:

(?!.*charge)(?!.*encode)(?!.*relate).*night.*

我要匹配的文本是:

归还了住宿费用,但仍存在建筑问题。喷洒化学药品会引起健康问题,并引起眼睛刺激。

我没有任何幸运。有人可以帮忙吗?

ES查询:

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

问题答案:

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

"value": "~(charge|encode|relate)night~(charge|encode|relate)",

要么

.*night.*&~(.*(charge|encode|relate).*)

带可选的(因为 默认情况下 为ON )

"flags" : "ALL"

它是如何工作的?

在常见的NFA正则表达式中,通常会有负面的环顾四周,以帮助限制更通用的模式(看起来像(?!...)或的样式(?<!...))。但是,在ElasticSearch中,您需要使用特定的
可选运算符

~(波浪号)是 补体 被用于*后它否定的原子权。原子可以是单个符号,也可以是一组内的一组子图案/替代物。

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

从而,

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

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

/^(?:(?!charge|encode|relate).)*night(?:(?!charge|encode|relate).)*$/

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

  • .*night.*-匹配整个线路(如.匹配任何象征,而是一个换行符,否则,使用(.|\n)*),用night
  • &-
  • ~(.*(charge|encode|relate).*)-不也行chargeencoderelate子在里面。

类似NFA Perl的正则表达式看起来像

/^(?!.*(charge|encode|relate)).*night.*$/


 类似资料:
  • 我有以下示例文本 当我应用以下正则表达式时,当我打印第一个捕获组时,我期望以下输出 但是我最终得到的是 在我看来,由于某种原因,否定的先行部分被忽略了,因此正则表达式与整个字符串匹配。 真正让我困惑的是,积极的前瞻性正如我所期望的那样工作。例如,使用在打印第一个捕获组时返回以下内容 这是有道理的,所以我真的很困惑为什么消极的前瞻性没有正常运作。

  • 我目前正在玩正则表达式,试图更好地理解它们,并且有一个我现在似乎正在努力的场景,因为我不知道这是否可以通过正则表达式来实现。 我有这样的文本字符串 该清单可能仍在进行中。我想匹配(选择)内部关键字之间的空格。因此,在第二行中,它将是和之间的空格。 和我能够匹配关键字中包含多个单词的行。将第一部分<代码>( 编辑:假设这些行之间还有一些其他文本,所以简单的< code>\b不能作为正则表达式使用。

  • 我试图捕捉两个最接近的短语之间的文本,包括这些短语,但消极的展望似乎在我的情况下不起作用。 因此,这是文本文件的一部分: 我需要捕捉每一对<代码> 我的正则表达式是:

  • 我想在Perl正则表达式中的非捕获组中使用负前瞻。到目前为止,我已经创建了一个表达式,它不允许将3个“字符对”放入字符串中 如果你看到组前有一个负面的展望,我想将这个表达式添加到一个组中。为了理解这一点,我将向您展示另一个只禁止一对或字符的示例。 如果在中测试这两个表达式https://regex101.com/您将看到,对于案例2中的字符串“MySampleString”,我有2个匹配信息。(全

  • 我想要一个 Java 正则表达式字符串,它可以在字符串中找到所有元音,除非它们: 是第一个字符或 下划线后面的下一个字符 AREA_ID变为AR_ID LONG_NAME变成 LNG_NM 孤独的家变成了ALN 我曾经使用过http://gskinner.com/RegExr,现在我有了下面的正则表达式来替换所有元音字母,除非它是起始字符 我想不出第二部分怎么弄(忽略紧跟在下划线后面的元音)。

  • 我有一些像这样的弦 我需要创建一个正则表达式,它将在没有空格的情况下获取内的所有内容。 使用下一个模式