简单的问题,谷歌正则表达式语法很难...
我正在浏览HortonWorks Hive tutorials (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、斯蒂特、球队ID、lgID、G、G_击球、AB、R、H、2B、3B、HR、RBI、SB、CS、BB、SO、IBB、HBP、SH、SF、GIDP、G_old aardsda01,2004,1,SFN,NL,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11 aardsda01,2006,1,CHN,NL,45,43,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,45 aardsda01,2007,1,CHA,AL,25,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
因此 PlayerID 位于第 1 列,年份位于第 2 列,R(运行)位于第 9 列。regexp_extract 如何成功提取此数据?
我对非捕获组很陌生,但在我看来整个事情都是一个非捕获组。另外,我习惯于看到 [0-9]{9} 形式的 {1}、{2} 或 {9},这意味着它与 9 位数字匹配。在这种情况下,它看起来像是指向某个东西的第 9 个匹配项,这个语法叫什么?
最佳答案
首先分解正则表达式:
^(?:([^,]*)\.?){n}
^
是String
的开头(?:...){n}
是重复n
次的非捕获组([^,]*)
是否定字符类,它匹配“not,
”零次或多次\.?
是可选的(文字).
那么,这是如何工作的?
非捕获组仅适用于 numeric quantifier ,即它使组中的整个模式重复 n
次。
捕获的实际模式位于捕获组([^,]*)
中。我不确定为什么存在可选的 .
,并且在示例数据中我没有看到任何以 .
结尾的输入,但我认为有一些。
发生的情况是该组被捕获n
次,但仅存储最后一次捕获,并且该捕获存储在第一个组中,即组1。这是regexp_extract中的默认值
.
因此,当模式在第一种情况下重复一次时,我们捕获逗号分隔数组上的第一个元素。当模式在第二个示例中重复两次时,我们捕获第二个元素。当该模式重复九次时,就会捕获第九个元素。
模式本身实际上非常可怕,因为它允许重复零长度模式,这意味着如果存在不匹配的模式,正则表达式引擎可以回溯很多。我想这对您来说不是问题,但通常是不好的做法。
最好通过添加 +
使 [^,]*
成为所有格:
^(?:([^,]*+)\.?){n}
或者使整个非捕获组原子化:
^(?>([^,]*)\.?){n}
关于Java/Hive 正则表达式解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20724960/