2011-12-13 48 views
10

我有一些問題REGEXP_EXTRACT:蜂巢REGEXP_EXTRACT古怪

我查詢一個製表符分隔的文件,我檢查了列有看起來像這樣的字符串:

abc.def.ghi 

現在,如果我這樣做:

select distinct regexp_extract(name, '[^.]+', 0) from dummy; 

MR作業運行時,它的工作原理,並從我得到的索引 「ABC」 0

但ñ嗷嗷,如果我想從指數1獲得 「高清」:

select distinct regexp_extract(name, '[^.]+', 1) from dummy; 

蜂巢失敗:

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 

我做得根本錯在這裏?

感謝, 馬里奧

回答

27

從文檔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)

索引不改變(因爲指數仍然referrs捕捉第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) 

如果不這樣做的斷言,那麼這將無法工作!

+0

謝謝,就是這樣。時間與配置單元提交功能請求:-) – Mario

+0

@Mario - 您的歡迎。添加了可能的解決方法正則表達式來縮短事情的解決方案。 – sln

+0

我希望我可以第二次給你投票 – Mario

1

我認爲你必須使 '羣體' 不?

select distinct regexp_extract(name, '([^.]+)', 1) from dummy; 

(未經測試)

我覺得它像Java庫和這應該工作,讓我知道雖然。

+0

哈哈,很奇怪,MR作業隨之運行,但它仍然返回索引0的內容! – Mario

+0

和我剛剛嘗試踢與索引2,然後它失敗與 2011-12-13 23:33:41,377階段1地圖= 0%,減少= 0% 2011-12-13 23:34: 01,465 Stage-1 map = 100%,reduce = 100% Ended Job = job_201112071152_0074出錯 FAILED:執行錯誤,從org.apache.hadoop.hive.ql.exec.MapRedTask返回代碼2 再次....奇怪的怪異怪異...... – Mario