Conditionally replace multiple instances of a char

2019-08-05 20:04发布

问题:

Related question:

Replace multiple instance of a character with a single instance in sql

Requirement:

I have the below strings:

Heelloo
Heeelloo
Heeeelloo
Heeeeeelloo
Heeeeeeeelloo
.
.
.
Heeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeelloo

Expected output:

If the instances of the letter 'e' is in multiples of 8, the expectation is 'ee'. For all other instances, it should be 'e'. So,

1. Heeeeeeeello should be Heello <<-- 8 instances of 'e' replaced by 'ee'

2. Heeeeeeeeeello should be Heeello <<-- 8 instances of 'e' replaced by 'ee' and then rest 2 'e''s replaced by a single 'e'.

3. Heeello should give Hello

Version I am using :

Microsoft SQL Server 2012 - 10.0.7365.0 (X64) Jul 28 2015 00:39:54 Copyright (c) 
Microsoft Corporation Parallel Data Warehouse (64-bit) on Windows NT 6.2 <X64> 
(Build 9200: )

回答1:

Based on T-SQL String Manipulation Tips and Techniques, Part 1 especially part Replacing Multiple Contiguous Spaces With a Single Space and idea of Peter Larsson, a SQL Server MVP:

Then, the solution involves three steps (assuming the token is ~):

  1. Replace in @str each occurrence of ' ' (space) with '~ ' (token plus space).
  2. Replace in the result of the previous step each occurrence of ' ~' (space plus token) with '' (an empty string).
  3. Replace in the result of the previous step each occurrence of '~ ' (token plus space) with ' ' (space).
CREATE TABLE #tab(val NVARCHAR(100));

INSERT INTO #tab
SELECT 'Hello'
UNION ALL SELECT 'Heello'
UNION ALL SELECT 'Heeello'
UNION ALL SELECT 'Heeeello'
UNION ALL SELECT 'Heeeeeello'
UNION ALL SELECT 'Heeeeeeeello'
UNION ALL SELECT 'Heeeeeeeeeello';

-- version for one vowel(it can be enhanced to handle other if needed)
SELECT val,
cleaned = REPLACE(
           REPLACE(
            REPLACE(
            REPLACE(REPLACE(val, REPLICATE('e', 8), '^^')
              , 'e', '~ ')
            , ' ~', '')
          , '~ ', 'e')
          ,'^^','ee')              
FROM #tab;

LiveDemo

Output:

╔════════════════╦═════════╗
║      val       ║ cleaned ║
╠════════════════╬═════════╣
║ Hello          ║ Hello   ║
║ Heello         ║ Hello   ║
║ Heeello        ║ Hello   ║
║ Heeeello       ║ Hello   ║
║ Heeeeeello     ║ Hello   ║
║ Heeeeeeeello   ║ Heello  ║
║ Heeeeeeeeeello ║ Heeello ║
╚════════════════╩═════════╝

From comment (alomost identical situation like in link above