Java/Hive正则表达式解释

Java/Hive正则表达式解释,java,regex,hive,Java,Regex,Hive,直截了当的问题,只是很难用谷歌搜索正则表达式语法 我正在浏览(Hive使用与Java相同的正则表达式),下面的SELECT语句使用正则表达式从可能的JSON数据中提取 INSERT OVERWRITE TABLE batting SELECT regexp_extract(col_value,'^(?:([^,]*)\.?){1}',1) player_id, regexp_extract(col_value,'^(?:([^,]*

直截了当的问题,只是很难用谷歌搜索正则表达式语法

我正在浏览(Hive使用与Java相同的正则表达式),下面的SELECT语句使用正则表达式从可能的JSON数据中提取

        INSERT OVERWRITE TABLE batting
        SELECT
        regexp_extract(col_value,'^(?:([^,]*)\.?){1}',1) player_id,
        regexp_extract(col_value,'^(?:([^,]*)\.?){2}',1) year,
        regexp_extract(col_value,'^(?:([^,]*)\.?){9}',1) run
        FROM temp_batting;
数据如下所示:

球员ID、年号、阶段、团队ID、lgID、G、G击球、AB、R、H、2B、3B、HR、RBI、SB、CS、BB、SO、IBB、HBP、SH、SF、GIDP、G_old AARDSD012004,1,SFN,NL,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11 AARDSD012006,1,CHN,NL,45,43,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,45 AARDSD012007,1,CHA,AL,25,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2

所以PlayerID在第1列,year在第2列,R(runs)在第9列。regexp\u extract是如何成功提取此数据的


我不熟悉非捕获组,但在我看来整个组都是非捕获组。而且,我习惯于看到{1}、{2}或{9}的形式为[0-9]{9},这意味着它匹配一个9位数字。在本例中,它看起来像是指向某物的第9个匹配项,这个语法叫什么

首先分离正则表达式:

^(?:([^,]*)\.?){n}
  • ^
    字符串的开头
  • (?:…){n}
    是重复
    n次的非捕获组
  • ([^,]*)
    是一个否定字符类,它与“not
    ”匹配零次或多次
  • \.?
    是可选的(文字)
那么,这是如何工作的呢

非捕获组仅用于,即,它使组中的整个图案重复
n次

正在捕获的实际模式位于捕获组
([^,]*)
中。我不确定为什么会有可选的
,我在示例数据中没有看到任何以
结尾的输入,但我假设有一些

所发生的情况是,组被捕获
n次
,但仅存储最后一次捕获,并且该捕获存储在第一个组中,即组1。这是
regexp\u extract
中的默认值

因此,当模式在第一种情况下重复一次时,我们捕获逗号分隔数组上的第一个元素。当模式在第二个示例中重复两次时,我们捕获第二个元素。当模式重复九次时,第九个元素被捕获

该模式本身实际上非常可怕,因为它允许重复零长度的模式,这意味着如果存在不匹配的模式,正则表达式引擎可以回溯很多。我想这对你来说不是一个问题,但这通常是一个坏习惯

最好通过添加一个
+
,使
[^,]*
具有所有格:

^(?:([^,]*+)\.?){n}
或者使整个非捕获组原子化:

^(?>([^,]*)\.?){n}

我相信在这个网站上练习和学习正则表达式的一个好方法是:


只需将表达式粘贴到那里,然后删除/替换其中的一部分。这比试图通过视觉破译正则表达式更有意义。

不使用正则表达式的另一种方法是使用split函数

select split('aardsda01,2006,1,CHN,NL,45,43,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,45',',')[0] as player_id,
split('aardsda01,2006,1,CHN,NL,45,43,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,45',',')[1] as year,
split('aardsda01,2006,1,CHN,NL,45,43,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,45',',')[1] as runs

首先,非常好的回答,谢谢。两个问题:我在你链接的页面上没有看到数字量词{n}。我看到它是以[0-9]{n}的方式使用的,但这是另一种情况,它匹配括号n次之间的内容。在这种情况下,有括号,而不是匹配n个连续时间,它看起来像是说只存储第n个匹配??第二,添加首字母^有什么意义?数据中没有空格,所以在我看来,一切都是字符串的开始。第三,*+在你的修正中起什么作用?以前从未见过这种情况。@user1956609
{n}
重复前面的模式
n
次-不管它是
[]
还是
()
-区别在于
[]
是单个字符,
()
是模式分组。请阅读我对该匹配的解释,因为该组位于重复模式中,只有最后一个匹配被捕获。最后,将
+
添加到量词中可以使其成为量词。