获取子字符串之前的字符串,直到字符的第 n 次出现
Get String Before a Substring till nth Occurrences of a Character
我正在处理一个字符串,我试图在出现任何子字符串“1:”之前获取一个字符串,直到出现 3 次字符“<”和出现 3 次字符“>”。
以下是字符串:
<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>1:<対象アイテム.ライフサイクル フェーズ> は <アイテム.Active> から <アイテム.破棄> に変更されました。2:<受影響的項目.生命週期階段>原為<物料.Active>現為<物料.報廢>3:<Données techniques affectées.Phase de cycle de vie>ÉTAIT<Données techniques.Active>EST<Données techniques.Obsolète>4:<受影响的物件.生命周期阶段>原为<物件.Active>现为<物件.报废>5:<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>6:<영향 받은 항목.수명 주기 단계>기존:<항목.Active>현재:<항목.폐기>7:<Задействованные элементы.Фаза жизненного цикла>ЯВЛЯЛСЯ<Элементы.Active>ЯВЛЯЕТСЯ<Элементы.Устарело>; <Affected Items.New Rev>WAS<>IS<1>1:<対象アイテム.新規リビジョン> は <> から <1> に変更されました。2:<受影響的項目.新版本>原為<>現為<1>3:<Données techniques affectées.Nouvelle révision>ÉTAIT<>EST<1>4:<受影响的物件.新版本>原为<>现为<1>5:<Betroffene Artikel.Neue Revision>WAR<>IST<1>6:<영향 받은 항목.새 수정 버전>기존:<>현재:<1>7:<Задействованные элементы.Новая ред.>ЯВЛЯЛСЯ<>ЯВЛЯЕТСЯ<1>
我想要以下子串:
<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>
和
<Affected Items.New Rev>WAS<>IS<1>
我可以使用下面的 SQL 获取第一个子字符串。但是很难得到第二个。
WITH CTE AS
(
SELECT '<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>1:<対象アイテム.ライフサイクル フェーズ> は <アイテム.Active> から <アイテム.破棄> に変更されました。2:<受影響的項目.生命週期階段>原為<物料.Active>現為<物料.報廢>3:<Données techniques affectées.Phase de cycle de vie>ÉTAIT<Données techniques.Active>EST<Données techniques.Obsolète>4:<受影响的物件.生命周期阶段>原为<物件.Active>现为<物件.报废>5:<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>6:<영향 받은 항목.수명 주기 단계>기존:<항목.Active>현재:<항목.폐기>7:<Задействованные элементы.Фаза жизненного цикла>ЯВЛЯЛСЯ<Элементы.Active>ЯВЛЯЕТСЯ<Элементы.Устарело>; <Affected Items.New Rev>WAS<>IS<1>1:<対象アイテム.新規リビジョン> は <> から <1> に変更されました。2:<受影響的項目.新版本>原為<>現為<1>3:<Données techniques affectées.Nouvelle révision>ÉTAIT<>EST<1>4:<受影响的物件.新版本>原为<>现为<1>5:<Betroffene Artikel.Neue Revision>WAR<>IST<1>6:<영향 받은 항목.새 수정 버전>기존:<>현재:<1>7:<Задействованные элементы.Новая ред.>ЯВЛЯЛСЯ<>ЯВЛЯЕТСЯ<1>'
AS "DETAILS"
FROM DUAL
)
select "DETAILS",
CASE
WHEN "DETAILS" != CONVERT ("DETAILS", 'US7ASCII')
THEN
CASE WHEN "DETAILS" LIKE '%1:%'
THEN
SUBSTR("DETAILS", 0, INSTR("DETAILS", '1:')-1)
ELSE
REGEXP_REPLACE ("DETAILS", '[^ -~]', '')
END
else
"DETAILS" end as details
FROM CTE
如有任何帮助,我们将不胜感激!
本文:https://blogs.oracle.com/sql/post/split-comma-separated-values-into-rows-in-oracle-database
解释了如何将 comma-separated 值字符串拆分成行。
因此,我们可以使用 <Affected Items.
作为分隔符。
这样做我们可以将这些行插入到临时 table 中,或者围绕它们进行查询,使用这个想法作为子字符串并提取每行的有价值部分,即从一开始直到第一次出现 :
.
我给出的link提供了这个例子:
with rws as (
select 'split,into,rows' str from dual
)
select regexp_substr (
str,
'[^,]+',
1,
level
) value
from rws
connect by level <=
length ( str ) - length ( replace ( str, ',' ) ) + 1;
VALUE
split
into
rows
并提供以下解释:
因此,如果您将 <Affected Items.
视为您的分隔符(而不是 ,
)并且生成行,则每一行都将包含有用的信息,直到它的第一个 :
.最后,您需要在结果前添加分隔符。
您可以使用:
WITH split (details, match, end_pos) AS (
SELECT details,
REGEXP_SUBSTR(details, '(.*?)\d+:', 1, 1, NULL, 1),
REGEXP_INSTR(details, '(.*?)\d+:', 1, 1, 1)
FROM table_name
UNION ALL
SELECT details,
REGEXP_SUBSTR(details, '(.*?)\d+:', end_pos, 1, NULL, 1),
REGEXP_INSTR(details, '(.*?)\d+:', end_pos, 1, 1)
FROM split
WHERE end_pos > 0
),
brackets (match, opening, closing) AS (
SELECT match,
INSTR(match, '<', -1, 3),
INSTR(match, '>', -1, 3)
FROM split
WHERE end_pos > 0
),
last_3_brackets (match) AS (
SELECT SUBSTR(match, LEAST(opening, closing)) AS match
FROM brackets
WHERE opening > 0
AND closing > 0
)
SELECT *
FROM last_3_brackets
WHERE match = CONVERT (match, 'US7ASCII')
其中,对于示例数据:
CREATE TABLE table_name (details) AS
SELECT '<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>1:<対象アイテム.ライフサイクル フェーズ> は <アイテム.Active> から <アイテム.破棄> に変更されました。2:<受影響的項目.生命週期階段>原為<物料.Active>現為<物料.報廢>3:<Données techniques affectées.Phase de cycle de vie>ÉTAIT<Données techniques.Active>EST<Données techniques.Obsolète>4:<受影响的物件.生命周期阶段>原为<物件.Active>现为<物件.报废>5:<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>6:<영향 받은 항목.수명 주기 단계>기존:<항목.Active>현재:<항목.폐기>7:<Задействованные элементы.Фаза жизненного цикла>ЯВЛЯЛСЯ<Элементы.Active>ЯВЛЯЕТСЯ<Элементы.Устарело>; <Affected Items.New Rev>WAS<>IS<1>1:<対象アイテム.新規リビジョン> は <> から <1> に変更されました。2:<受影響的項目.新版本>原為<>現為<1>3:<Données techniques affectées.Nouvelle révision>ÉTAIT<>EST<1>4:<受影响的物件.新版本>原为<>现为<1>5:<Betroffene Artikel.Neue Revision>WAR<>IST<1>6:<영향 받은 항목.새 수정 버전>기존:<>현재:<1>7:<Задействованные элементы.Новая ред.>ЯВЛЯЛСЯ<>ЯВЛЯЕТСЯ<1>' FROM DUAL;
输出:
MATCH
<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>
<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>
<Affected Items.New Rev>WAS<>IS<1>
<Betroffene Artikel.Neue Revision>WAR<>IST<1>
db<>fiddle here
我正在处理一个字符串,我试图在出现任何子字符串“1:”之前获取一个字符串,直到出现 3 次字符“<”和出现 3 次字符“>”。
以下是字符串:
<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>1:<対象アイテム.ライフサイクル フェーズ> は <アイテム.Active> から <アイテム.破棄> に変更されました。2:<受影響的項目.生命週期階段>原為<物料.Active>現為<物料.報廢>3:<Données techniques affectées.Phase de cycle de vie>ÉTAIT<Données techniques.Active>EST<Données techniques.Obsolète>4:<受影响的物件.生命周期阶段>原为<物件.Active>现为<物件.报废>5:<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>6:<영향 받은 항목.수명 주기 단계>기존:<항목.Active>현재:<항목.폐기>7:<Задействованные элементы.Фаза жизненного цикла>ЯВЛЯЛСЯ<Элементы.Active>ЯВЛЯЕТСЯ<Элементы.Устарело>; <Affected Items.New Rev>WAS<>IS<1>1:<対象アイテム.新規リビジョン> は <> から <1> に変更されました。2:<受影響的項目.新版本>原為<>現為<1>3:<Données techniques affectées.Nouvelle révision>ÉTAIT<>EST<1>4:<受影响的物件.新版本>原为<>现为<1>5:<Betroffene Artikel.Neue Revision>WAR<>IST<1>6:<영향 받은 항목.새 수정 버전>기존:<>현재:<1>7:<Задействованные элементы.Новая ред.>ЯВЛЯЛСЯ<>ЯВЛЯЕТСЯ<1>
我想要以下子串:
<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>
和
<Affected Items.New Rev>WAS<>IS<1>
我可以使用下面的 SQL 获取第一个子字符串。但是很难得到第二个。
WITH CTE AS
(
SELECT '<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>1:<対象アイテム.ライフサイクル フェーズ> は <アイテム.Active> から <アイテム.破棄> に変更されました。2:<受影響的項目.生命週期階段>原為<物料.Active>現為<物料.報廢>3:<Données techniques affectées.Phase de cycle de vie>ÉTAIT<Données techniques.Active>EST<Données techniques.Obsolète>4:<受影响的物件.生命周期阶段>原为<物件.Active>现为<物件.报废>5:<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>6:<영향 받은 항목.수명 주기 단계>기존:<항목.Active>현재:<항목.폐기>7:<Задействованные элементы.Фаза жизненного цикла>ЯВЛЯЛСЯ<Элементы.Active>ЯВЛЯЕТСЯ<Элементы.Устарело>; <Affected Items.New Rev>WAS<>IS<1>1:<対象アイテム.新規リビジョン> は <> から <1> に変更されました。2:<受影響的項目.新版本>原為<>現為<1>3:<Données techniques affectées.Nouvelle révision>ÉTAIT<>EST<1>4:<受影响的物件.新版本>原为<>现为<1>5:<Betroffene Artikel.Neue Revision>WAR<>IST<1>6:<영향 받은 항목.새 수정 버전>기존:<>현재:<1>7:<Задействованные элементы.Новая ред.>ЯВЛЯЛСЯ<>ЯВЛЯЕТСЯ<1>'
AS "DETAILS"
FROM DUAL
)
select "DETAILS",
CASE
WHEN "DETAILS" != CONVERT ("DETAILS", 'US7ASCII')
THEN
CASE WHEN "DETAILS" LIKE '%1:%'
THEN
SUBSTR("DETAILS", 0, INSTR("DETAILS", '1:')-1)
ELSE
REGEXP_REPLACE ("DETAILS", '[^ -~]', '')
END
else
"DETAILS" end as details
FROM CTE
如有任何帮助,我们将不胜感激!
本文:https://blogs.oracle.com/sql/post/split-comma-separated-values-into-rows-in-oracle-database
解释了如何将 comma-separated 值字符串拆分成行。
因此,我们可以使用 <Affected Items.
作为分隔符。
这样做我们可以将这些行插入到临时 table 中,或者围绕它们进行查询,使用这个想法作为子字符串并提取每行的有价值部分,即从一开始直到第一次出现 :
.
我给出的link提供了这个例子:
with rws as (
select 'split,into,rows' str from dual
)
select regexp_substr (
str,
'[^,]+',
1,
level
) value
from rws
connect by level <=
length ( str ) - length ( replace ( str, ',' ) ) + 1;
VALUE
split
into
rows
并提供以下解释:
因此,如果您将 <Affected Items.
视为您的分隔符(而不是 ,
)并且生成行,则每一行都将包含有用的信息,直到它的第一个 :
.最后,您需要在结果前添加分隔符。
您可以使用:
WITH split (details, match, end_pos) AS (
SELECT details,
REGEXP_SUBSTR(details, '(.*?)\d+:', 1, 1, NULL, 1),
REGEXP_INSTR(details, '(.*?)\d+:', 1, 1, 1)
FROM table_name
UNION ALL
SELECT details,
REGEXP_SUBSTR(details, '(.*?)\d+:', end_pos, 1, NULL, 1),
REGEXP_INSTR(details, '(.*?)\d+:', end_pos, 1, 1)
FROM split
WHERE end_pos > 0
),
brackets (match, opening, closing) AS (
SELECT match,
INSTR(match, '<', -1, 3),
INSTR(match, '>', -1, 3)
FROM split
WHERE end_pos > 0
),
last_3_brackets (match) AS (
SELECT SUBSTR(match, LEAST(opening, closing)) AS match
FROM brackets
WHERE opening > 0
AND closing > 0
)
SELECT *
FROM last_3_brackets
WHERE match = CONVERT (match, 'US7ASCII')
其中,对于示例数据:
CREATE TABLE table_name (details) AS
SELECT '<Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete>1:<対象アイテム.ライフサイクル フェーズ> は <アイテム.Active> から <アイテム.破棄> に変更されました。2:<受影響的項目.生命週期階段>原為<物料.Active>現為<物料.報廢>3:<Données techniques affectées.Phase de cycle de vie>ÉTAIT<Données techniques.Active>EST<Données techniques.Obsolète>4:<受影响的物件.生命周期阶段>原为<物件.Active>现为<物件.报废>5:<Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet>6:<영향 받은 항목.수명 주기 단계>기존:<항목.Active>현재:<항목.폐기>7:<Задействованные элементы.Фаза жизненного цикла>ЯВЛЯЛСЯ<Элементы.Active>ЯВЛЯЕТСЯ<Элементы.Устарело>; <Affected Items.New Rev>WAS<>IS<1>1:<対象アイテム.新規リビジョン> は <> から <1> に変更されました。2:<受影響的項目.新版本>原為<>現為<1>3:<Données techniques affectées.Nouvelle révision>ÉTAIT<>EST<1>4:<受影响的物件.新版本>原为<>现为<1>5:<Betroffene Artikel.Neue Revision>WAR<>IST<1>6:<영향 받은 항목.새 수정 버전>기존:<>현재:<1>7:<Задействованные элементы.Новая ред.>ЯВЛЯЛСЯ<>ЯВЛЯЕТСЯ<1>' FROM DUAL;
输出:
MATCH <Affected Items.Lifecycle Phase>WAS<Items.Active>IS<Items.Obsolete> <Betroffene Artikel.Lebenszyklusphase>WAR<Artikel.Active>IST<Artikel.Veraltet> <Affected Items.New Rev>WAS<>IS<1> <Betroffene Artikel.Neue Revision>WAR<>IST<1>
db<>fiddle here