首页 > 解决方案 > 正则表达式获取 ES 查询中的所有 field_names

问题描述

我正在尝试获取弹性搜索查询的所有 field_names。

示例:name:"Tom" AND city:("SanFransico" OR "Mexico") AND id:("123:34 X2")应该给我namecityid

我已经尝试过使用([^:\s]+):正则表达式,它会给我所有的比赛,并且对于每场比赛,第一组会给我 field_name。

但是这个正则表达式在某些极端情况下失败,其中 field_value 包含列。由于弹性搜索接受 field_values 中的列(或任何弹性搜索保留字),当它们被引号包围或用反斜杠(“ \”)转义时,考虑到所有情况,我们如何编写正则表达式?

以下是我观察到的几个使用正则表达式失败的案例([^:\s]+):

  1. name:"Tom" AND city:("SanFransico" OR "Mexico") AND id:("123:34 X2")应该只给出名称、城市和 ID。但是使用我的正则表达式,我得到了名字、城市、id,(“123.
  2. name:"Tom" AND city:("SanFransico" OR "Mexico") AND id:123\:34是有效的 ES 查询并且应该只给出名称、城市和 ID。但是使用我的正则表达式,我得到了名字,城市,id,123。

标签: regexelasticsearch

解决方案


第三版:

只需稍作调整即可处理条件周围的大括号。

(\w+)\s*:\s*(("[^"]+")|(\([^)]+\))|[^\s]+)

我刚刚将第二版的第一部分更改([^\s:]+)(\w+).

该模式[^\s:]+匹配不是空格或冒号(包括大括号)的每个字符。

该模式\w+仅匹配单词字符,这在大多数情况下应该是合适的,除非您的字段名包含 then 以外的字符[a-zA-Z0-9_]。但希望这种情况永远不会发生;-)

看例子


第二版:

下面可能是一个稍微好一点的版本,但我担心总是有可能创建一个导致误报的 ES 查询,因为查询可能是任意复杂的。你能做的最好的就是调整你的正则表达式,直到它满足你的需要。

([^\s:]+)\s*:\s*(("[^"]+")|(\([^)]+\))|[^\s]+)

描述:

([^\s:]+)= 字段名

\s*:\s*= 用可选空格包围的冒号

"[^"]+"= 包围的字段值"

\([^)]+\)= 包围的字段值()

[^\s]+= 文字字段值

看例子


第一个版本:

我刚刚(^|\s)在您的正则表达式前面添加了一个:这意味着字段名位于字符串 ( ) 或 ( )(^|\s)([^:\s]+): 的开头,紧跟在空格 ( ) 之后。然后,该字段的名称位于捕获组 2 中。^|\s

看例子


推荐阅读