[英]hive regexp_extract weirdness
我在使用regexp_extract時遇到了一些問題:
我在一個制表符分隔的文件上查詢,我正在檢查的列包含如下所示的字符串:
abc.def.ghi
現在,如果我這樣做:
select distinct regexp_extract(name, '[^.]+', 0) from dummy;
MR作業運行,它工作,我從索引0得到“abc”。
但現在,如果我想從索引1獲得“def”:
select distinct regexp_extract(name, '[^.]+', 1) from dummy;
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
日志文件說:
java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row
我在這里做了一些根本錯誤的事嗎?
謝謝,馬里奧
從文檔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)
編輯
我對此重新感興趣,只是一個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}更改為'segment'是什么需要(這確實是第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)
如果它沒有做斷言,那么這將不起作用!
我認為你必須讓'團體'沒有?
select distinct regexp_extract(name, '([^.]+)', 1) from dummy;
(另)
我認為它的行為類似於java庫,這應該可行,但請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.