文化感知的 initcap

来自 PostgreSQL 维基
跳转到导航跳转到搜索

代码片段

文化感知的 initcap

适用于 PostgreSQL

任何版本

使用语言

SQL

依赖于


作者:Peter Geoghegan ("sternocera")


以下是“文化感知的 initcap”的实现,可以作为 initcap 的直接替代,前提是输入为英文。它解决了我在使用常规 initcap 时经常遇到的许多问题,特别是涉及所有格撇号的问题,也包括各种常见的缩写(isn't,can't,won't,I'm,you've,you're)。它实现了这一点,同时不会影响像 O'Shaughnessy 和 O'Sullivan 这样爱尔兰姓氏的人。

使用常规 initcap:SELECT initcap($$O'SULLIVAN'S friend DOESN'T LIVE HERE anymore$$)

输出:"O'Sullivan'S Friend Doesn'T Live Here Anymore"

使用 cul_initcap:SELECT cul_initcap($$O'SULLIVAN'S friend DOESN'T LIVE HERE anymore$$)

输出:"O'Sullivan's Friend Doesn't Live Here Anymore"

CREATE OR REPLACE FUNCTION cul_initcap(input_val text) RETURNS text AS
$function_body$

  SELECT 
    replace(
      replace(
        replace(
          replace(
            replace(
              replace(
                replace(
                  regexp_replace(initcap($1), 
                      $$'(([MSTD]|Ve|Re|Ll))([^[:upper:][:lower:]]|$)$$, 
                      $$'{@*#!\1!#*@}\3$$, 
                      'g'
                      )
                  , '{@*#!M!#*@}', 'm')
                , '{@*#!S!#*@}', 's')
              , '{@*#!T!#*@}', 't')
            , '{@*#!D!#*@}', 'd')
          , '{@*#!Ve!#*@}', 've')
        , '{@*#!Re!#*@}', 're')
      , '{@*#!Ll!#*@}', 'll');

$function_body$
LANGUAGE 'sql' IMMUTABLE STRICT;

我的实现的一个显著限制是,它会错误地将“魔法大括号括起来的值”转换为相应的输出值: '{@*#!T!#*@}' ,'{@*#!S!#*@}', '{@*#!M!#*@}', '{@*#!Ve!#*@}'(以及其他)分别变为 't'、's'、'm' 和 've'。我怀疑这通常不是什么大问题。如果这是一个问题,请使用更复杂的魔法大括号,这些大括号在生产环境中存在的字符串中出现的可能性更小。