ITPUB论坛-中国最专业的IT技术社区

 找回密码
 注册
查看: 4186|回复: 6

[每日一题] PL/SQL Challenge 每日一题:2017-1-4 字符串截取

[复制链接]
论坛徽章:
454
秀才
日期:2015-08-18 09:49:27秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01状元
日期:2015-09-09 10:34:21榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01
发表于 2017-1-7 04:13 | 显示全部楼层 |阅读模式

最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

每两周的优胜者可获得itpub奖励的技术图书一本。

以往旧题索引:
http://www.itpub.net/forum.php?m ... =typeid&typeid=1808

原始出处:
http://www.plsqlchallenge.com/

作者:        Kim Berg Hansen

运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品

我有一张表,保存着书的章节标题:

create table plch_chapters (
   id    integer primary key
, title varchar2(40)
)
/

insert into plch_chapters values (1, 'The Introduction')
/
insert into plch_chapters values (2, 'The Prerequisites')
/
insert into plch_chapters values (3, 'That Methodology')
/
insert into plch_chapters values (4, 'Case Studies')
/
insert into plch_chapters values (5, 'The Summary')
/
commit
/

确定标题之后,我觉得标题中含有的那些"The" 和 "That"不太好看,所以我想要修改标题,如果一个标题以"Th"开头,则取下一个空格之后的内容作为新标题。

我有一个未完成的查询来获取章节的新标题:

select id
     , ##REPLACE##
          as new_title
  from plch_chapters
order by id
/

哪些选项包含了NEW_TITLE列的表达式,可以用来取代##REPLACE##,使得查询返回如下输出:

        ID NEW_TITLE
---------- ----------------------------------------
         1 Introduction
         2 Prerequisites
         3 Methodology
         4 Case Studies
         5 Summary

(A)
substr(title, instr(title, ' ') + 1)

(B)
substr(title, instr(title, ' ', instr(title, 'Th')) + 1)

(C)
substr(title, regexp_instr(title, 'Th.*?\s'))

(D)
substr(title, regexp_instr(title, 'Th.*?\s') + 4)

(E)
substr(title, regexp_instr(title, 'Th.*?\s')
               + length(regexp_substr(title, 'Th.*?\s'))
      )

(F)
substr(title, regexp_instr(title, 'Th.*?\s')
               + nvl(length(regexp_substr(title, 'Th.*?\s')), 0)
      )
      
(G)
substr(title, regexp_instr(title, 'Th.*?\s', 1, 1, 1))      

(H)
regexp_substr(title, '(Th.*?\s)?(.*)$', 1, 1, null, 2)

(I)
regexp_replace(title, '^Th.*?\s')
论坛徽章:
18
秀才
日期:2016-04-29 15:11:10秀才
日期:2017-04-05 13:27:59秀才
日期:2017-04-05 13:23:10秀才
日期:2017-04-05 13:23:10秀才
日期:2017-04-05 13:23:10秀才
日期:2017-04-05 13:22:59秀才
日期:2017-03-02 10:35:32秀才
日期:2017-01-20 11:06:21秀才
日期:2017-01-20 11:00:36秀才
日期:2017-01-20 11:04:31
发表于 2017-1-7 09:09 | 显示全部楼层
我选BFGHI
A、将所有字符串第一个单词替过滤掉,这是错误的。
B、正确,先取"Th"开头位置再,再取下一个空格位置,然后截取。
C、使用正则表达式但找到的是Th开头单词的起始位置,这样截取是错误的。
D、Th开头单词的起始位置+4,这样截取是错误的.
E、未做空值处理,这是错误的。
F、正确,使用正则表达式但找到Th单词后的起始位置,然后截取。
GH、正确,返回字符之后的位置。
I、正确,这样更简洁,直接排除一个Th匹配串后截取。

使用道具 举报

回复
论坛徽章:
393
雪佛兰
日期:2013-12-04 20:30:02马上有钱
日期:2014-03-11 11:59:122014年世界杯参赛球队:喀麦隆
日期:2014-07-11 12:10:53马上有对象
日期:2014-04-09 16:19:542014年世界杯参赛球队: 洪都拉斯
日期:2014-06-25 08:25:55itpub13周年纪念徽章
日期:2014-09-28 10:55:55itpub13周年纪念徽章
日期:2014-10-01 15:27:22itpub13周年纪念徽章
日期:2014-10-09 12:04:18马上有钱
日期:2014-10-14 21:37:37马上有钱
日期:2015-01-22 00:39:13
发表于 2017-1-7 13:29 | 显示全部楼层
不用正则也可以
a=instr(s,'th')
b=instr(s,' ')
substr(s,decode(a,1,b+1,1),decode(a,1,100,b-1))

使用道具 举报

回复
论坛徽章:
393
雪佛兰
日期:2013-12-04 20:30:02马上有钱
日期:2014-03-11 11:59:122014年世界杯参赛球队:喀麦隆
日期:2014-07-11 12:10:53马上有对象
日期:2014-04-09 16:19:542014年世界杯参赛球队: 洪都拉斯
日期:2014-06-25 08:25:55itpub13周年纪念徽章
日期:2014-09-28 10:55:55itpub13周年纪念徽章
日期:2014-10-01 15:27:22itpub13周年纪念徽章
日期:2014-10-09 12:04:18马上有钱
日期:2014-10-14 21:37:37马上有钱
日期:2015-01-22 00:39:13
发表于 2017-1-7 13:30 | 显示全部楼层
〇〇 发表于 2017-1-7 13:29
不用正则也可以
a=instr(s,'th')
b=instr(s,' ')

比b好懂一点

使用道具 举报

回复
论坛徽章:
3
复活蛋
日期:2012-02-15 22:12:02ITPUB 11周年纪念徽章
日期:2012-10-09 18:06:20优秀写手
日期:2013-12-18 09:29:13
发表于 2017-1-9 23:57 | 显示全部楼层
今天晚上先回答前三个

A,没有获得想李的结果,把title的值中第一个空格前的字符都去掉了,没有区别是否符合要求

B,这个得出的结果是楼主想要的人,但是以目前插入的值是正确的,如果有不是以Th开头,但是Th在中间的话,这个表达式也可能不正确。

C,同上,没有限制以Th开头,如果Th在中间结果不一定正确



使用道具 举报

回复
论坛徽章:
3
复活蛋
日期:2012-02-15 22:12:02ITPUB 11周年纪念徽章
日期:2012-10-09 18:06:20优秀写手
日期:2013-12-18 09:29:13
发表于 2017-1-10 00:00 | 显示全部楼层
补充一下,
C,当Th开头的字符满足条件时,regexp_instr函数返回的结果是1,这样既使满足条件也将会全部输出整个字符串,也不是想要的结果

使用道具 举报

回复
论坛徽章:
3
复活蛋
日期:2012-02-15 22:12:02ITPUB 11周年纪念徽章
日期:2012-10-09 18:06:20优秀写手
日期:2013-12-18 09:29:13
发表于 2017-1-10 00:04 | 显示全部楼层
D,第4条 Case Studies经过regexp_inst函数返回的值为0,然后+4后,再使用substr函数把整个字符串截断了,也不是想要的结果

使用道具 举报

回复
论坛徽章:
454
秀才
日期:2015-08-18 09:49:27秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01状元
日期:2015-09-09 10:34:21榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01
 楼主| 发表于 2017-1-10 05:33 | 显示全部楼层
答案BFGHI, 2楼得奖。

A: 我们取出了第一个空格之后的所有东西,对于第四章来说就去掉了"Case"这个词,导致如下的错误输出:

        ID NEW_TITLE
---------- ----------------------------------------
         1 Introduction
         2 Prerequisites
         3 Methodology
         4 Studies
         5 Summary

B:(不推荐)
在这选项中,我们选取的是"Th"之后的第一个空格位置。在第四章我们没有"Th",所以最里面的INSTR返回零,告诉外层的INSTR选取第零个空格,这毫无道理,会使得INSTR返回零,就使得我们的SUBSTR从头获取整个字符串。

C:
REGEXP_INSTR返回搜索串中第一个字符的位置,此时SUBSTR对所有情形都返回整个字符串,得到这个错误输出:

        ID NEW_TITLE
---------- ----------------------------------------
         1 The Introduction
         2 The Prerequisites
         3 That Methodology
         4 Case Studies
         5 The Summary

D: 加上固定的四个字符的偏移量于事无补,它返回这个错误输出:

        ID NEW_TITLE
---------- ----------------------------------------
         1 Introduction
         2 Prerequisites
         3  Methodology
         4 e Studies
         5 Summary

E: 加上找到表达式的长度是可以的,但是对于第四章,REGEXP_SUBSTR返回了NULL, 使得LENGTH返回NULL, 结果使得SUBSTR也返回NULL, 得到这个错误输出:

        ID NEW_TITLE
---------- ----------------------------------------
         1 Introduction
         2 Prerequisites
         3 Methodology
         4
         5 Summary

F:(不推荐)
加上NVL解决了前一选项的问题。

G: 使用REGEXP_INSTR的第五个参数比加上表达式长度的方法容易多了。第五个参数的缺省值是0,意味着返回的是找到的搜索子串的第一个字符的位置,而此处的参数值1则意味着返回的是搜索子串之后的第一个字符的位置,这正是我们所需要的。

H: 如果不用REGEXP_INSTR 和 SUBSTR , 我们也可以用REGEXP_SUBSTR。这时我们就能用第六个参数,指出我们要返回的是搜索表达式中的哪个子项
I: 或者我们也可以将前一选项的逻辑逆转,使得我们将搜索表达式替换为NULL,这是最简单容易的方法。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 虎吧 老博客 知识索引树 读书频道 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛 | SAP ERP系统
CopyRight 1999-2011 itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表