我在使用regexp_extract时遇到了一些问题:
我在一个制表符分隔的文件上查询,我正在检查的列包含如下所示的字符串:
abc.def.ghi
Run Code Online (Sandbox Code Playgroud)
现在,如果我这样做:
select distinct regexp_extract(name, '[^.]+', 0) from dummy;
Run Code Online (Sandbox Code Playgroud)
MR作业运行,它工作,我从索引0得到"abc".
但现在,如果我想从索引1获得"def":
select distinct regexp_extract(name, '[^.]+', 1) from dummy;
Run Code Online (Sandbox Code Playgroud)
Hive失败了:
2011-12-13 23:17:08,132 Stage-1 map = 0%, reduce = 0%
2011-12-13 23:17:28,265 Stage-1 map = 100%, reduce = 100%
Ended Job = job_201112071152_0071 with errors
FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.MapRedTask
Run Code Online (Sandbox Code Playgroud)
日志文件说:
java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row
Run Code Online (Sandbox Code Playgroud)
我在这里做了一些根本错误的事吗?
谢谢,马里奥
小智 33
从文档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'.
Run Code Online (Sandbox Code Playgroud)
所以,在你的情况下,要获得点后的文本,这样的东西可能会起作用:
regexp_extract(name, '\.([^.]+)', 1)
或者这个
regexp_extract(name, '[.]([^.]+)', 1)
编辑
我对此重新感兴趣,只是一个fyi,可能有一个快捷方式/解决方法.
看起来你想要一个用点.字符分隔的特定段,这几乎就像拆分一样.
如果它被量化不止一次,那么使用的正则表达式引擎很可能会覆盖一个组.
你可以利用这样的东西来利用它:
返回第一个段: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).
并且在第{N}次迭代后它仍然返回捕获缓冲区1.
在这里它被打破了
^ # 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)
Run Code Online (Sandbox Code Playgroud)
如果它没有做断言,那么这将不起作用!