【问题标题】:get everything before a string including itself oracle获取字符串之前的所有内容,包括其自身 oracle
【发布时间】:2018-04-01 02:51:41
【问题描述】:

我需要在包含自身的字符串之前获取所有内容,然后将其替换为其他内容。例如,如果我在列中有一个值为 28/29/81/732536/1496071 的值,那么我想选择 81 之前的所有内容,包括它自己,即我想从中选择 28/29/81 并将其替换为其他字符串。我已经尝试了以下方法,但我只得到了 28/29。

 SELECT SUBSTR(eda.ATTRIBUTE_VALUE, 0, INSTR(eda.ATTRIBUTE_VALUE, '81')-2) AS output, ATTRIBUTE_VALUE
FROM EVENT_DYNAMIC_ATTRIBUTE eda

【问题讨论】:

  • 显然需要增加第三个参数——将-2改为+1左右。但是,如果输入中不存在字符串'81',您将遇到问题。然后:你真的要匹配'/81/',而不是'/19812/' 中的81
  • 81 可以是 / 和 / 之间的任何数字,即它可以是 81 或 3543、543545 之类的,在我的查询中匹配字符串来自参数
  • 你没有理解我的问题。如果attribute_value 是28/29/81/732536,这是否匹配253?它是732536 的子字符串 - 这足以形成匹配吗?
  • 您的意思是,您将 / 字符之间的数字视为段,并询问是否也应在这些段中覆盖部分匹配。我在下面的回答假设应该涵盖部分匹配。如果不应该那么我可以提出这样的建议:如果你需要匹配'123',你可以在'/'中搜索'/123/' || eda.ATTRIBUTE_VALUE || '/' 和我的回答一样……
  • @mathguy,它应该匹配 / 和 / 之间的整数

标签: sql oracle substring substr


【解决方案1】:

你可以使用这样的东西:

SELECT 'STRING_TO_REPLACE_WITH' || SUBSTR(eda.ATTRIBUTE_VALUE, INSTR(eda.ATTRIBUTE_VALUE, '81') + 2) AS output
FROM EVENT_DYNAMIC_ATTRIBUTE eda;

【讨论】:

  • 这给了我类似“STRING_TO_REPLACE_WITH09004”的属性值“1/63911/1509004”,id 不会一直是 2 位数字。
  • 我只需要一个数字前面的所有内容,包括结果中的它自己。该数字只能在 / 和 / 之间匹配。基本上这些是实体的祖先路径,当它移动到另一个父级时,我想用新路径替换旧路径到该实体,以便在移动后它有正确的路径。
【解决方案2】:

当“令牌”(在您的示例中为 '81')出现在两个斜杠之间,或者在字符串的开头和斜杠之前,或者在最后一个斜杠之后,该解决方案必须起作用的字符串。如果“81”作为“标记”的一部分出现(在斜线之间或第一个斜线之前或最后一个斜线之后),则它不应匹配。另外,如果“token”出现了不止一次,它应该只被替换一次(用它之前的所有东西),如果它根本没有出现,那么原始字符串应该保持不变。

如果这些是规则,那么您可以执行如下所示的操作。如果任何规则不同,可以修改解决方案以适应。

我创建了一些输入字符串来测试 WHERE 子句中的所有这些情况。我还在 WITH 子句的第二个子查询中创建了“搜索令牌”和“替换文本”。整个 WITH 子句应该被替换——它不是解决方案的一部分,它只是为了我自己的测试。在主查询中,您应该使用实际的表名和列名(和/或硬编码文本)。

我使用 REGEXP_REPLACE 来查找标记并将其及其之前的所有内容(但不是斜线之后,如果有的话)替换为替换文本.我必须小心搜索令牌后的斜线;为此,我在 REGEXP_REPLACE 的替换字符串中使用了反向引用。

with
  event_dynamic_attribute ( attribute_value ) as (
    select '28/29/81/732536/1496071' from dual union all
    select '29/33/530813/340042/88'  from dual union all
    select '81/6883/3902/81/993'     from dual union all
    select '123/45/6789/81'          from dual
  ),
  substitution ( token, replacement ) as (
    select '81', 'mathguy is great'  from dual
  )
select attribute_value,
       regexp_replace (attribute_value, '(^|.*?/)' || token || '(/|$)',
                                        replacement || '\2', 1, 1) new_attrib_value
from   event_dynamic_attribute cross join substitution
;

ATTRIBUTE_VALUE         NEW_ATTRIB_VALUE                       
----------------------- ----------------------------------------
28/29/81/732536/1496071 mathguy is great/732536/1496071         
29/33/530813/340042/88  29/33/530813/340042/88                  
81/6883/3902/81/993     mathguy is great/6883/3902/81/993       
123/45/6789/81          mathguy is great

【讨论】:

  • 太棒了,完美!!
猜你喜欢
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 2014-06-07
  • 2017-09-12
  • 2018-08-08
  • 1970-01-01
相关资源
最近更新 更多