【问题标题】:remove special characters from query without using the replace function不使用替换功能从查询中删除特殊字符
【发布时间】:2021-07-07 19:26:08
【问题描述】:

我的查询中有一些外语名称。问题是,我不知道所有特殊字符都在哪里,所以使用 REPLACE 函数将无济于事,因为有超过 500,000 行。例如,一些外国名字是这样出现的:

我希望名称显示为“COLLEGE BOREAL DARTS APPLIQUES ET DE TECHNOLOGIE”

有没有办法在不使用替换功能的情况下实现这一点?这样它也适用于列表中的其他名称

我尝试了我在另一篇文章中看到的类似方法:

SELECT
CTE.COLLEGE_NAME COLLATE Cyrillic_General_CI_AI
FROM SCHOOLS cte

但它没有工作。如果有人可以帮我解决这个问题,那就太好了!谢谢

【问题讨论】:

  • 查看此 OTN 论坛讨论 (community.oracle.com/tech/developers/discussion/4146087/…)。它建议使用 TRANSLATE 函数并包含几个可能有帮助的示例(除非您有未涵盖的字符)。
  • 我有此处未涵盖的字符,例如“@”和商标符号
  • 所以包括它们;我想应该不会太难。
  • 我不想包含符号和其他字符,但正如我所说,我只想要字母,本文使用翻译功能,这不是我要找的
  • 我认为 Littlefoot 指的是在翻译中包含那些,而不是在结果中。你为什么不想使用替换或翻译 - 因为有太多的可能性?以及适用于结果的基本规则 - 听起来你可能只想要 ASCII 字符,减号;那正确吗?除了你只说字母;但是你保留了空格,那么数字呢?最后一个查询here 是否适用于您的真实数据?

标签: oracle


【解决方案1】:

您似乎在谈论重音字符和特殊字符。正如@Sayan 展示的那样,您可以使用nlssort 删除重音符号,但除了必须处理大小写更改之外,它不会删除诸如商标符号之类的东西(您可能期望或想要提到0 - ' ™' 被转换为 'tm' 这很聪明但在这里没有帮助,它也抛出了翻译(as shown here,在 Sayan 的代码中添加示例)。

另一种可能对您有用的方法是使用 convert(Oracle 推荐 not to do)或 utl_raw/utl_i18n 函数将您的值转换为纯 ASCII,从而处理重音(希望所有其中;我没有进行广泛的测试,并且链接到的讨论 @Littlefoot 显示了很多变化),并用 ? 替换任何其他非 ASCII 值,然后您可以方便地将其与其他标点符号和符号一起删除:

select college_name,
  regexp_replace(
    utl_i18n.raw_to_char(utl_i18n.string_to_raw(college_name, 'US7ASCII'), 'US7ASCII'),
    '[[:punct:]]',
    null) as result
from schools

您的示例和另一个带有商标符号的示例给出:

COLLEGE_NAME RESULT
COLLÈGE BORÉAL D’ARTS APPLIQUÉS ET DE TECHNOLOGIE COLLEGE BOREAL DARTS APPLIQUES ET DE TECHNOLOGIE
Collectives™ on Stack Overflow Collectives on Stack Overflow

db<>fiddle 包括一些变化;但不要使用convert *8-)

【讨论】:

  • 谢谢,这个工作,有趣的是,ORACLE 不推荐 CONVERT,因为对我来说,这两个代码工作得很好:```select regexp_replace(utl_i18n.raw_to_char(utl_i18n.string_to_raw(' Collège Boréal D'Arts Appliqués Et De Technologie?', 'US7ASCII'), 'US7ASCII'), '[[:punct:]]', null) 作为对偶的结果; ``` 和 ``` regexp_replace(CONVERT(' Collège Boréal D'Arts Appliqués ÄNí et de Technologie?', 'US7ASCII'),'[[:punct:]]') ``` 只是想知道你能不能告诉我为什么在第一个 sql 代码的末尾添加 NULL 很重要?
  • @comp_user - null 并不重要,它只是明确表明您正在删除标点符号,而不是用任何东西替换它;但它是一个可选参数,如果您省略它,将没有任何区别。是的,convert 在我的小提琴中也可以工作,但它可能不在具有不同字符集的数据库中,而且通常最好避免 Oracle 不鼓励的事情 *8-)
  • 非常感谢@Alex Poole!非常感谢您的解释
【解决方案2】:

当然,您可以从字符中删除上升/元音变音。

首先看这个例子:

with t(n,name) as (
select 1, 'Löwenbrauerei' from dual union all
select 2, 'LÖwenbrauerei' from dual union all
select 3, 'Lowenbrauerei' from dual union all
select 4, 'LOwenbrauerei' from dual 
)
select
   n
  ,name
  ,utl_raw.cast_to_varchar2(nlssort(name, 'NLS_SORT=BINARY_AI')) name_AI
from t;

结果:

        N NAME           NAME_AI
---------- -------------- --------------------
         1 Löwenbrauerei  lowenbrauerei
         2 LÖwenbrauerei  lowenbrauerei
         3 Lowenbrauerei  lowenbrauerei
         4 LOwenbrauerei  lowenbrauerei

如您所见,NLSSORT(..., 'NLS_SORT=BINARY_AI') 删除了所有上升并全部更改为小写字符,因此您只需恢复原始的大写/小写字符。例如,您可以将其与 translate 一起使用:

with t(n,name) as (
select 1, 'Löwenbrauerei' from dual union all
select 2, 'LÖwenbrauerei' from dual union all
select 3, 'Lowenbrauerei' from dual union all
select 4, 'LOwenbrauerei' from dual 
)
select
  n
  ,name 
  ,upper(name)
  ,lower(utl_raw.cast_to_varchar2(nlssort(name, 'NLS_SORT=BINARY_AI'))) name_AI_lower
  ,upper(utl_raw.cast_to_varchar2(nlssort(name, 'NLS_SORT=BINARY_AI'))) name_AI_upper
  ,translate(
      translate(
           name
          ,upper(name)
          ,upper(utl_raw.cast_to_varchar2(nlssort(name, 'NLS_SORT=BINARY_AI')))
      )
      ,lower(name)
      ,utl_raw.cast_to_varchar2(nlssort(name, 'NLS_SORT=BINARY_AI'))
  ) as name_ascent_removed
from t;

结果:

         N NAME           UPPER(NAME)    NAME_AI_LOWER        NAME_AI_UPPER        NAME_ASCENT_REMOVED
---------- -------------- -------------- -------------------- -------------------- --------------------------------------------------------
         1 Löwenbrauerei  LÖWENBRAUEREI  lowenbrauerei        LOWENBRAUEREI        Lowenbrauerei
         2 LÖwenbrauerei  LÖWENBRAUEREI  lowenbrauerei        LOWENBRAUEREI        LOwenbrauerei
         3 Lowenbrauerei  LOWENBRAUEREI  lowenbrauerei        LOWENBRAUEREI        Lowenbrauerei
         4 LOwenbrauerei  LOWENBRAUEREI  lowenbrauerei        LOWENBRAUEREI        LOwenbrauerei

ps。也许您可以在忽略它们的客户端上设置代码页/字体...

【讨论】:

  • afaIk 这里没有魔杖——你必须像这样手动编码。不过,函数会是更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-14
  • 2016-04-12
  • 2021-08-09
  • 1970-01-01
  • 2016-09-13
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多