簡體   English   中英

hive regexp_extract古怪

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM