bigquery не жадный REGEXP_EXTRACT

# #regex #google-bigquery

Вопрос:

Как извлечь кратчайшее совпадение(ленивое, не жадное) для функции REGEXP_SUBSTR?

Регулярное .*? выражение должно возвращать не жадный результат.

Но bigquery REGEXP_SUBSTR возвращает {"r": [{"l": 10, "s": 1, "t": ["1"]}, {"l": 100, "s": 3, "t": ["3", "4"]} вместо {"l": 100, "s": 3, "t": ["3", "4"]} с регулярным выражением = r'{.*?"t": ["3", "4"]}'

Есть ли какие-то намеки на это?

Примечание: JSONPATH не работает для меня (т. Е. фильтр массива jsonpath не поддерживается bigquery.)

 WITH tbl AS (
  SELECT r'{"r": [{"l": 10, "s": 1, "t": ["1"]}, {"l": 100, "s": 3, "t": ["3", "4"]}]}' AS jstr
)
SELECT 
   jstr
  ,REGEXP_EXTRACT(jstr, r'{.*?"t": ["3", "4"]}') AS e1
FROM tbl
 

Ответ №1:

BigQuery поддерживает пути JSON. Я думаю, что это сработает для вас:

 JSON_QUERY(jstr, '$.r[0].t')
 

Что касается вашего регулярного выражения, то, насколько я могу судить, оно соответствует стандартному поведению регулярного выражения.

Я думаю, проблема в том, что вы ожидаете, что не жадный оператор найдет кратчайшее возможное соответствие для этой подстроки, но на самом деле это не то, для чего он предназначен. Не Жадный оператор просто говорит «потребляйте как можно меньше повторений при поиске соответствия»-и регулярное выражение находит первую скобку, потребляет как можно меньше символов, пока не достигнет » [3, 4]», и останавливается-успех!

Если бы вы были в жадном режиме, он продолжал бы искать другое возможное совпадение » [3, 4]». В не-жадном режиме он останавливается на первом, но не возвращается, чтобы получить абсолютно наименьшую возможную последовательность.

Комментарии:

1. JSON_QUERY с фильтром не работает с bigquery. Я бы хотел найти t с помощью [‘3’, ‘4’], но не t с помощью [‘1’]. Возможно, мне следует использовать JSON_QUERY_ARRAY с перекрестным соединением и фильтрованием по предложению where.

2. Спасибо за ваше объяснение non-greedy режима поиска : )

3. А, понял насчет фильтра. Ваш план JSON_QUERY_ARRAY звучит разумно.