Oracle SQL 查找字符串并向后工作
Oracle SQL Find A String & Work Backwards
我想做的是在结果中找到一个特定的字符串,然后从该字符串向后工作以获得我需要的内容。举个例子,假设我的结果是 "This thing is heavy at 500KG no matter what"。我想找到 "KG" 然后向后工作以获得“500KG”。
我想从 KG 向后计算的原因是结果可以有不同的字符串,例如 "This thing is heavy at 500 kg" 或“500 - This thing is heavy 500Kg”等。唯一不变的是 KG(即使在它的不同的状态)。
我正在使用 regexp_instr 和 substr 将结果缩小到类似 "This thing is heavy at 500KG" 的范围 - 本质上是找到 KG 并删除它后面的所有内容。
建议?
Oracle 的正则表达式引擎目前不支持先行或后行,因此无法找到您在问题中描述的正确字符串。
话虽如此,您只需使用 REGEXP_SUBSTR()
即可;像下面这样的东西可能会起作用(取决于你的数据):
regexp_substr(str, '\d+\s?kg', 1, 1, 'i')
这将搜索任意数量的数字,后跟可选的 space,再后跟字符串 kg
。其他参数是位置(从 1 开始)、出现(第一个)和匹配参数(不区分大小写)。
这会让你得到你想要的:
SQL> with str (s) as (
2 select 'This thing is heavy at 500 kg'
3 from dual
4 union all
5 select '500 - This thing is heavy 500Kg'
6 from dual
7 )
8 select regexp_substr(s, '\d+\s?kg', 1, 1, 'i')
9 from str;
REGEXP_SUBSTR(S,'\D+\S?KG',1,1,'I')
---------------------------------------------------
500 kg
500Kg
SQL>
之所以有效,是因为您正在搜索 kg
的号码。因此,如果此字符串后没有数字,则不会返回它。
根据您的数据和您想要的输出,这可能还不够。例如,如果千克也可以表示为 k.g.
,并且您想删除数字和大写字符串之间的 space,您可能想要执行如下操作:
SQL> with str (s) as (
2 select 'This thing is heavy at 6872 kg'
3 from dual
4 union all
5 select '157 - This thing is heavy 248K.g'
6 from dual
7 )
8 select regexp_substr(s, '(\d+)\s?k\.?g', 1, 1, 'i', 1) || 'KG'
9 from str;
REGEXP_SUBSTR(S,'(\D+)\S?K\.?G',1,1,'I',1)||'KG'
-------------------------------------------------------------------
6872KG
248KG
SQL>
我添加的最后一个参数是要返回的子表达式,由组 (\d+)
标识。这将挑选出第一个(唯一的)子表达式,这将是您的号码并将字符串 KG
连接到该号码的末尾。
如果您使用的是 Oracle 10g,您可以执行以下操作(@Ben 的回答在 11g 或 12c 中工作得很好):
SELECT REGEXP_REPLACE(mystring, '^.*?(\d+)\s*k\.?g.*$', 'KG', 1, 1, 'i')
FROM mytable
这里不能使用REGEXP_SUBSTR()
的原因是这个函数的10g版本中没有最后一个参数(subexpression
)
如果你想捕捉各种测量单位,那可能会更困难,但并非不可能,例如:
SELECT REGEXP_REPLACE(mystring, '^.*?(\d+)\s*(k?g|lbs?|oz).*$', '', 1, 1, 'i')
FROM mytable
这将捕获克 (g
)、千克 (kg
)、磅 (lb
或 lbs
) 和盎司 (oz
)。
我想做的是在结果中找到一个特定的字符串,然后从该字符串向后工作以获得我需要的内容。举个例子,假设我的结果是 "This thing is heavy at 500KG no matter what"。我想找到 "KG" 然后向后工作以获得“500KG”。
我想从 KG 向后计算的原因是结果可以有不同的字符串,例如 "This thing is heavy at 500 kg" 或“500 - This thing is heavy 500Kg”等。唯一不变的是 KG(即使在它的不同的状态)。
我正在使用 regexp_instr 和 substr 将结果缩小到类似 "This thing is heavy at 500KG" 的范围 - 本质上是找到 KG 并删除它后面的所有内容。
建议?
Oracle 的正则表达式引擎目前不支持先行或后行,因此无法找到您在问题中描述的正确字符串。
话虽如此,您只需使用 REGEXP_SUBSTR()
即可;像下面这样的东西可能会起作用(取决于你的数据):
regexp_substr(str, '\d+\s?kg', 1, 1, 'i')
这将搜索任意数量的数字,后跟可选的 space,再后跟字符串 kg
。其他参数是位置(从 1 开始)、出现(第一个)和匹配参数(不区分大小写)。
这会让你得到你想要的:
SQL> with str (s) as (
2 select 'This thing is heavy at 500 kg'
3 from dual
4 union all
5 select '500 - This thing is heavy 500Kg'
6 from dual
7 )
8 select regexp_substr(s, '\d+\s?kg', 1, 1, 'i')
9 from str;
REGEXP_SUBSTR(S,'\D+\S?KG',1,1,'I')
---------------------------------------------------
500 kg
500Kg
SQL>
之所以有效,是因为您正在搜索 kg
的号码。因此,如果此字符串后没有数字,则不会返回它。
根据您的数据和您想要的输出,这可能还不够。例如,如果千克也可以表示为 k.g.
,并且您想删除数字和大写字符串之间的 space,您可能想要执行如下操作:
SQL> with str (s) as (
2 select 'This thing is heavy at 6872 kg'
3 from dual
4 union all
5 select '157 - This thing is heavy 248K.g'
6 from dual
7 )
8 select regexp_substr(s, '(\d+)\s?k\.?g', 1, 1, 'i', 1) || 'KG'
9 from str;
REGEXP_SUBSTR(S,'(\D+)\S?K\.?G',1,1,'I',1)||'KG'
-------------------------------------------------------------------
6872KG
248KG
SQL>
我添加的最后一个参数是要返回的子表达式,由组 (\d+)
标识。这将挑选出第一个(唯一的)子表达式,这将是您的号码并将字符串 KG
连接到该号码的末尾。
如果您使用的是 Oracle 10g,您可以执行以下操作(@Ben 的回答在 11g 或 12c 中工作得很好):
SELECT REGEXP_REPLACE(mystring, '^.*?(\d+)\s*k\.?g.*$', 'KG', 1, 1, 'i')
FROM mytable
这里不能使用REGEXP_SUBSTR()
的原因是这个函数的10g版本中没有最后一个参数(subexpression
)
如果你想捕捉各种测量单位,那可能会更困难,但并非不可能,例如:
SELECT REGEXP_REPLACE(mystring, '^.*?(\d+)\s*(k?g|lbs?|oz).*$', '', 1, 1, 'i')
FROM mytable
这将捕获克 (g
)、千克 (kg
)、磅 (lb
或 lbs
) 和盎司 (oz
)。