REGEXP_REPLACE 捕获组

Posted

技术标签:

【中文标题】REGEXP_REPLACE 捕获组【英文标题】:REGEXP_REPLACE capturing groups 【发布时间】:2015-04-19 23:02:06 【问题描述】:

我想知道是否有人可以帮助我了解如何使用 Hive 的 regexp_replace 函数来捕获正则表达式中的组并在替换字符串中使用这些组。

我有一个我正在解决的示例问题,它涉及日期修改。在此示例中,我的目标是获取一个与 SimpleDateFormat 解析不兼容的字符串日期,并进行小幅调整以使其兼容。日期字符串(如下所示)需要在字符串中的偏移符号 (+/-) 前加上“GMT”。

所以,给定输入:

  '2015-01-01 02:03:04 +0:00' 
  -or-
  '2015-01-01 02:03:04 -1:00' 

我想要输出:

  '2015-01-01 02:03:04 GMT+0:00'
  -or-
  '2015-01-01 02:03:04 GMT-1:00'

这是一个我“认为”可行的语句的简单示例,但我得到了奇怪的输出。

Hive 查询:

select regexp_replace('2015-01-01 02:03:04 +0:00', ' ([+-])', ' GMT\1');

实际结果:

2015-01-01 02:03:04 GMT10:00

注意“\1”应该输出匹配的组,而是用数字“1”替换匹配的组。

有人可以帮我理解在替换字符串中引用/输出匹配组的正确方法吗?

谢谢!

【问题讨论】:

【参考方案1】:

Hive 支持的表示法(至少对于 0.14,我想我记得对于 0.13.x 也是这种方式)对于正则表达式反向引用似乎是 $1 用于捕获组 1,$2 用于捕获组 2,等等。它看起来像是基于(甚至可能由)replaceAll method from the Matcher class 实现的。这是该文档的相关部分:

如上所述,美元符号可以被视为对捕获的子序列的引用,并且反斜杠用于转义替换字符串中的文字字符。

所以我想你想要的是这样的:

select regexp_replace('2015-01-01 02:03:04 +0:00', ' ([+-])', ' GMT$1');

例如:

hive> select regexp_replace('2015-01-01 02:03:04 +0:00', ' ([+-])', ' GMT$1');
OK
2015-01-01 02:03:04 GMT+0:00
Time taken: 0.072 seconds, Fetched: 1 row(s) 
hive> select regexp_replace('2015-01-01 02:03:04 -1:00', ' ([+-])', ' GMT$1');
OK
2015-01-01 02:03:04 GMT-1:00
Time taken: 0.144 seconds, Fetched: 1 row(s)

【讨论】:

【参考方案2】:

在尝试反向引用 REGEXP_REPLACE 中捕获的组时,“\1”和“$1”都对我有用。 然而这有效: https://www.logicbig.com/tutorials/core-java-tutorial/java-regular-expressions/group-ref-in-replacement.html

一个例子:(用连字符代替散列)

hive> select REGEXP_REPLACE('foo#bar','(?<tag1>foo)#(?<tag2>bar)', '$tag1-$tag2');
OK
foo-bar
Time taken: 0.085 seconds, Fetched: 1 row(s)

Hope this is helpful.

【讨论】:

以上是关于REGEXP_REPLACE 捕获组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 regexp_replace 仅替换捕获组而不是完整匹配字符串

Oracle regexp_replace 挑选出模式匹配组

Oracle 正则表达式函数-REGEXP_REPLACE 使用例子

hive函数REGEXP_REPLACE用法

hive函数REGEXP_REPLACE用法

hive函数REGEXP_REPLACE用法