Oracle REGEXP的几个不声明

时间:2019-03-10 18:42:23

标签: sql regex oracle

我有一个字符串,其中有4个名称,用逗号分隔。 4个名字中的3个在里面都有严格的标识符,而最后一个没有标识符。字符串中名称的顺序是随机的。如何使用oracle REGEXP获得不带标识符的名称?

示例字符串:'a. Name1, b. Name2, Name3, c-f Name4'

严格标识符为'a.''b.''c-f'

name1name2name4我可以通过这种方式获得:

select 
regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )a.[^,]+($|,)') as name1,
regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )b.[^,]+($|,)') as name2,
regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )c\-f[^,]+($|,)') as name4
from dual

我想使用这样的名称来获取name3:

'(^|, )((NOT("a."))and(NOT("b."))and(NOT("c-f")))([^,]+($|,)'

但是我不知道如何使用REGEXP。在Oracle中有可能吗?

3 个答案:

答案 0 :(得分:2)

这将匹配第三个后向参考点(任何用方括号括起来的图案)。

REGEXP_REPLACE(
   yourStringColumn,
   'a\. (.*), b\. (.*), (.*), c-f (.*)',
   '\3'
)

我使用的模式中有4个反向引用,每个都是您要查找的名称。模式的其余部分(在反向引用之外)是您描述的模式的固定部分。请记住要逃脱句号,这样它就不会被当作通配符('\.'

编辑:

如果它们可以以任何顺序排列,我最好的尝试是在逗号(或字符串的开始/结尾)之间找到一个本身不包含逗号或空格(空格表示有前缀)的项目。< / p>

SELECT
  regexp_replace(
    'c-f Name1, Name2, b. Name3, a. Name4', 
    '(^|.+, )([^, ]+)($|, .+)',
    '\2'
  )
FROM
  dual
;

答案 1 :(得分:0)

必须是正则表达式吗?因为,如果没有,那么SUBSTR + INSTR组合也可以完成这项工作。

@app.route("/" , methods = ['POST']) #loading from db for modal updating
def loadQualToUpdate():
updateBtnId = request.form['updateBtn']
updateQualifications = db.qualifications.findOne({
    "_id": updateBtnId
})
qualName = request.form['qualNameUpdate']

updateDB = {
    "$set": {
        "qualificationName": qualName,
    }
}
db.qualifications.updateOne(updateQualifications, updateDB)
return redirect(url_for('setupQual')) #setupQual page has the Table

[编辑,根据MatBailie的评论]

SQL> with test (col) as
  2    (select 'a. Name1, b. Name2, Name3, c-f Name4' from dual)
  3  select
  4    trim(substr(col, instr(col, '.', 1, 1) + 1,
  5                     instr(col, ',', 1, 1) - instr(col, '.', 1, 1) - 1)) str1,
  6    trim(substr(col, instr(col, '.', 1, 2) + 1,
  7                     instr(col, ',', 1, 2) - instr(col, '.', 1, 2) - 1)) str2,
  8    trim(substr(col, instr(col, ',', 1, 2) + 1,
  9                     instr(col, ',', 1, 3) - instr(col, ',', 1, 2) - 1)) str3,
 10    trim(substr(col, instr(col, 'c-f', 1, 1) + 4)) str4
 11  from test;

STR1  STR2  STR3  STR4
----- ----- ----- -----
Name1 Name2 Name3 Name4

SQL>

[编辑#2]

由于标识符可以放置在任何地方,所以这样的代码怎么样?

SQL> with test (col) as
  2    (select 'a. Name1, b. Name2, Name3, c-f Name4' from dual)
  3  select
  4    trim(substr(col, instr(col, 'a.', 1, 1) + 2,
  5                     instr(col, ', b.', 1, 1) - instr(col, 'a.', 1, 1) - 2)) str1,
  6    trim(substr(col, instr(col, 'b.', 1, 1) + 2,
  7                     instr(col, ',', 1, 2) - instr(col, 'b.', 1, 1) - 2)) str2,
  8    trim(substr(col, instr(col, ',', 1, 2) + 1,
  9                     instr(col, ',', 1, 3) - instr(col, ',', 1, 2) - 1)) str3,
 10    trim(substr(col, instr(col, 'c-f', 1, 1) + 4)) str4
 11  from test;

STR1  STR2  STR3  STR4
----- ----- ----- -----
Name1 Name2 Name3 Name4

SQL>

答案 2 :(得分:0)

我了解我可以多次使用REGEXP_REPLACE函数:

select 
regexp_replace(
regexp_replace(
regexp_replace(
'a. Name1, b. Name2, Name3, c-f Name4',
'(^|, | )a\.[^,]+($|,)'),
'(^|, | )b\.[^,]+($|,)'),
'(^|, | )c\-f[^,]+($|,)') as name3
from dual

MatBailie,谢谢您使用REGEXP_REPLACE的想法!

相关问题