#php #amazon-s3 #sdk #jmespath
#php #amazon-s3 #sdk #jmespath
Вопрос:
Возможно ли переместить preg_match
приведенный ниже поиск в фильтр поиска JMESPATH с помощью contains
? Я нашел пример contains
в руководстве по JMESPATH, но я не уверен, поддерживает ли синтаксис объединение строк фильтра каким-либо образом с помощью 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;
}
}
Ответ №1:
Предполагая, что документ имеет формат, подобный этому:
{
"Contents": [
{
"Key": "some/path/css_example",
...
},
{
"Key": "another/path/js_example",
...
},
{
"Key": "blah/blah/other_example",
...
}
]
}
(Я бы проверил, но у меня нет учетных данных AWS, и на удивление сложно найти примеры формата JSON ответа S3 list-objects.)
Попробуйте выполнить запрос:
Contents[].Key|[?contains(@, 'css_') || contains(@, 'js_')]
В этом случае Contents[].Key
выбираются только ключи (как в вашем примере). Канал |
используется для сброса проекции, чтобы мы работали со всем списком, а не с каждым ключом в отдельности. [?...]
фильтрует список, чтобы выбрать только ключи, которые соответствуют логическому условию. contains
Функция может использоваться несколькими способами, но мы используем ее здесь, чтобы увидеть, содержит ли первый аргумент в виде строк ( @
текущий элемент в списке) второй аргумент, подстроку, которую мы ищем. Мы объединяем два использования contains
функции с оператором или ||
, чтобы элемент соответствовал, если выполняется любое условие.
Ответ №2:
Конечно, выражение or — это то, что существует в JMESpath.
Но тогда вы могли бы даже пойти дальше и полностью отказаться от цикла for и извлечь ключи, используя выражение функций.
Учитывая данные:
{
"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"
}
}
Или даже проще, поскольку contains
возвращает true
или false
, уже:
$keys = $s3_results->search(
'Contents[].Key[?contains(@, `js_`) || contains(@, `css_`)]'
);