Ответ 1
Из документов https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF видно, что regexp_extract() - это извлечение записей/строк данных, которые вы хотите извлечь.
Кажется, что он работает с первым найденным (а затем и выходом) в отличие от глобального. Поэтому индекс ссылается на группу захвата.
0 = весь матч
1 = группа захвата 1
2 = захватить группу 2 и т.д.
Перефразировано из руководства:
regexp_extract('foothebar', 'foo(.*?)(bar)', 2)
^ ^
groups 1 2
This returns 'bar'.
Итак, в вашем случае, чтобы получить текст после точки, что-то вроде этого может работать: regexp_extract(name, '\.([^.]+)', 1)
или это regexp_extract(name, '[.]([^.]+)', 1)
редактировать
Я снова заинтересовался этим, просто к вашему сведению, для вас может быть ярлык/обходной путь.
Похоже, вы хотите, чтобы определенный сегмент был отделен точкой .
персонаж, который почти как сплит.
Более чем вероятно, что используемый механизм регулярных выражений перезаписывает группу, если она определяется количественно более одного раза.
Вы можете воспользоваться этим примерно так:
Возвращает первый сегмент: abc
.def.ghi regexp_extract(name, '^(?:([^.]+)\.?){1}', 1)
Возвращает второй сегмент: abc. def
.ghi regexp_extract(name, '^(?:([^.]+)\.?){2}', 1)
Возвращает третий сегмент: abc.def. ghi
regexp_extract(name, '^(?:([^.]+)\.?){3}', 1)
Индекс не изменяется (поскольку индекс по-прежнему ссылается на группу 1), изменяется только повторение регулярных выражений.
Некоторые заметки:
-
Это регулярное выражение
^(?:([^.]+)\.?){n}
имеет проблемы.
Требуется что-то между точками в сегменте, иначе регулярное выражение не будет соответствовать...
-
Это может быть
^(?:([^.]*)\.?){n}
но это будет соответствовать, даже если есть меньше чем n-1 точек,
включая пустую строку. Это, вероятно, не желательно.
Есть способ сделать это, когда для этого не требуется текст между точками, но все же требуется как минимум n-1 точек.
При этом используется буфер подтверждения 2 и захвата в качестве флага.
^(?:(?!\2)([^.]*)(?:\.|$())){2}
, все остальное тоже самое.
Так что, если он использует регулярные выражения в стиле Java, то это должно работать. regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){2}', 1)
заменить {2} на любой "сегмент" необходимо (это делает сегмент 2).
и он все еще возвращает буфер захвата 1 после {N} '-й итерации.
Здесь это сломано
^ # Begining of string
(?: # Grouping
(?!\2) # Assertion: Capture buffer 2 is UNDEFINED
( [^.]*) # Capture buffer 1, optional non-dot chars, many times
(?: # Grouping
\. # Dot character
| # or,
$ () # End of string, set capture buffer 2 DEFINED (prevents recursion when end of string)
) # End grouping
){3} # End grouping, repeat group exactly 3 (or N) times (overwrites capture buffer 1 each time)
Если он не делает утверждений, то это не сработает!