Skip to content

Instantly share code, notes, and snippets.

@pv8
Created January 6, 2014 23:04
Show Gist options
  • Save pv8/8291531 to your computer and use it in GitHub Desktop.
Save pv8/8291531 to your computer and use it in GitHub Desktop.
Alternative function to PostgreSQL builtin initcap(text) with support for accented words.
-- ========================================================================
-- Function: initcap2(text)
-- Return Type: text
-- Description: Alternative function to builtin initcap(text). This function
-- convert the first letter of each word to upper case and
-- the rest to lower case EVEN IF the sentence has accented words.
-- Example: initcap2('welcome to CHAMPS-ÉLYSÉES')
-- Result: 'Welcome To Champs-Élysées'
--
-- License: MIT
-- Copyright (c) 2013 Pablo O Vieira (povieira)
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
-- ========================================================================
CREATE OR REPLACE FUNCTION initcap2(text)
RETURNS text
LANGUAGE plpgsql
AS
$body$
DECLARE
sentence TEXT := '';
word_array TEXT[];
word TEXT;
word_out TEXT;
BEGIN
sentence := $1;
IF sentence is NULL THEN
RETURN NULL;
END IF;
word_array := regexp_split_to_array($1, E'[\\[\\]\^\$\.\|\?\*\+\(\)\\~`\!@#%&\\-\\_+={}''"<>:;, ]');
FOREACH word IN ARRAY word_array
LOOP
word_out := translate(upper(left(word, 1)), text 'áéíóúàèìòùãõâêîôôäëïöüç', text 'ÁÉÍÓÚÀÈÌÒÙÃÕÂÊÎÔÛÄËÏÖÜÇ')
|| translate(lower(substring(word, 2)), text 'ÁÉÍÓÚÀÈÌÒÙÃÕÂÊÎÔÛÄËÏÖÜÇ', text 'áéíóúàèìòùãõâêîôôäëïöüç');
sentence := regexp_replace(sentence, word, word_out);
END LOOP;
RETURN trim(sentence);
END;
$body$
IMMUTABLE
COST 100
/
@pv8
Copy link
Author

pv8 commented Jan 10, 2014

Actually, I realized that initcap2 was a waste of time since I could just use the PostgreSQL Collation Support (since version 9.x) when database is not using UTF-8:

select initcap('welcome to CHAMPS-ÉLYSÉES' collate "fr_FR")

will result:

initcap
-------------------------
Welcome To Champs-Élysées'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment