JMESPATH可以执行“包含X或Y”搜索/过滤器吗?

问题描述

是否可以使用preg_match将下面的contains搜索移到JMESPATH搜索过滤器中?我在JMESPATH tutorial中找到了contains的示例,但是我不确定该语法是否支持使用OR组合过滤字符串。

  $s3_results = $s3_client->getPaginator('ListObjects',['Bucket' => $config['bucket']]);
  // Narrow S3 list down to files containing the strings "css_" or "js_".
  foreach ($s3_results->search('Contents[].Key') as $key) {
    if (preg_match("/(css_|js_)/",$key)) {
      $s3_keys[] = $key;
    }
  }

解决方法

假设文档的格式如下:

{
    "Contents": [
        {
            "Key": "some/path/css_example",...
        },{
            "Key": "another/path/js_example",{
            "Key": "blah/blah/other_example",...
        }
    ]
}

(我会检查,但我没有AWS凭证,而且很难找到S3列表对象响应的JSON格式的示例。)

尝试查询:

Contents[].Key|[?contains(@,'css_') || contains(@,'js_')]

在这种情况下,Contents[].Key仅选择键(如您的示例)。管道|用于重置投影,以便我们对整个列表进行操作,而不是分别对每个键进行操作。 [?...]过滤列表以仅选择满足布尔条件的键。 contains函数可以以多种方式使用,但是我们在这里使用它来查看第一个参数作为字符串(@,列表中的当前项目)是否包含第二个参数,即我们的子字符串。重新寻找。我们将contains函数的两种用法与或运算符||结合使用,以便在任一条件为true时,项匹配。

,

当然,or expression是JMESPath中确实存在的东西。

但是,您甚至可以走得更远,完全放弃for循环,并使用functions expression来获取密钥。

给出数据:

{
  "Contents": [
    {
      "Key": [
        "css_foo","js_bar","brown_fox"
      ]
    },{
      "Key": [
        "js_foo","css_bar","lazy_dog"
      ]
    }
  ]
}

然后

$keys = $s3_results->search(
  'Contents[].Key[?(contains(@,`js_`) == `true` || contains(@,`css_`) == `true`)]'
);

将为您提供以下二维数组(因为有两个内容):

array(2) {
  [0] =>
  array(2) {
    [0] =>
    string(7) "css_foo"
    [1] =>
    string(6) "js_bar"
  }
  [1] =>
  array(2) {
    [0] =>
    string(6) "js_foo"
    [1] =>
    string(7) "css_bar"
  }
}