SQL - 需要帮助解析字段的文本

时间:2015-07-24 12:32:26

标签: sql oracle regexp-substr

我有一个select查询,它会获取一个包含复杂数据的字段。我需要以指定的格式解析该数据。请帮助您的专业知识:

selected string = complexType|ChannelCode=PB - Phone In A Box|IncludeExcludeIndicator=I

expected output - PB|I

请帮我写一个sql正则表达式来完成这个输出。

1 个答案:

答案 0 :(得分:0)

找出正则表达式的第一步是能够用简单的语言来描述它。根据我们所知的(以及其他人所说的,确实需要更多信息),你的帖子必须做出一些假设。

我通过这样描述它来抨击它,它基于你提供的样本数据:我想要一组一个或多个字符遵循等号,但不包括以下空格或队伍的尽头。输出应该是这些字符集,由管道分隔,按从左到右阅读时在字符串中遇到的顺序排列。我的假设基于您的测试数据:字符串中只存在2个等号,最后一个数据元素后面没有空格,而是行的末尾。可以使用该信息构建正则表达式,但您还需要考虑可能会更改正则表达式的其他事实。

  • 可能有两个以上的等号吗?
  • 等号后可能有空数据元素吗?
  • 等号后面的数据集可以包含一个或多个空格吗?

所有这些都会影响正则表达式的设计方式。总而言之,基于所提供的数据和所述的假设,接下来我将构建一个描述字符串的正则表达式(实际上从简单语言转换为正则语言),围绕我们想要保留的数据集进行分组,然后将字符串替换为由管道分隔的数据集。

SQL> with tbl(str) as (
  2    select 'complexType|ChannelCode=PB - Phone In A Box|IncludeExcludeIndicator=I' from dual
  3  )
  4  select regexp_replace(str, '^.*=([^ ]+).*=([^ ]+)$', '\1|\2') result from tbl;

RESU
----
PB|I

匹配正则表达式解释说:

^        Match the beginning of the line
.        followed by any character
*        followed by 0 or more 'any characters' (refers to the previous character class)
=        followed by an equal sign
(        start remembered group 1 
[^ ]+    which is a set of one or more characters that are not a space
)        end remembered group one
.*=      followed by any number of any characters but ending in an equal sign
([^ ]+)  followed by the second remembered group of non-space characters
$        followed by the end of the line

替换字符串解释:

\1       The first remembered group
|        a pipe character
\2       the second remember group

请注意,此答案适用于您所显示的确切样本数据,并且可能无法在所有情况下使用。您需要分析将要使用的数据。无论如何,这些步骤应该让您在面对具有挑战性的正则表达式时开始解决问题。重要的是要考虑可能存在的所有类型的数据和模式(或NULL),并允许正则表达式中的所有情况,以便您返回准确的数据。

编辑:检查一下,它会在等号后面解析所有值并允许空值:

SQL> with tbl(str) as (
  2    select 'a=zz|complexType|ChannelCode=PB - Phone In A Box|IncludeExcludeIndicator=I - testing|test1=|test2=test2 - testing' from dual
  3  )
  4  select regexp_substr(str, '=([^ |]*)( |||$)', 1, level, null, 1) output, level
  5  from tbl
  6  connect by level <= regexp_count(str, '=')
  7  ORDER BY level;

OUTPUT                    LEVEL
-------------------- ----------
zz                            1
PB                            2
I                             3
                              4
test2                         5

SQL>