Share via

SQL PATINDEX find the first non-matching special character

Dávid Laczkó 1 Reputation point
2022-05-24T13:21:28.96+00:00

I was writing a functionality that is the inverse of padding, e.g. from 00123 get 123, and I wanted a function that removes any given character. I use PATINDEX with [^] (Wildcard - Character(s) Not to Match), and I tested the special characters, and for my both positive and negative surprise, I could do nothing to escape these. Namely: as a positive surprise, characters _, %, and [ doesn't even need escaping, and as a negative surprise, characters ^ and ] can not be searched without escaping, and I could not escape them the way it is described at the LIKE operator, neither on a 2012 nor on a 2019 version.

Some examples without escaping:

SELECT
 PATINDEX(N'%[^_]%', N'_a_bc__') as [_]
 ,PATINDEX(N'%[^%]%', N'%a%bc%%') as [%]
 ,PATINDEX(N'%[^^]%', N'^a^bc^^') as [^]
 ,PATINDEX(N'%[^[]%', N'[a[bc[[') as [[]
 ,PATINDEX(N'%[^]]%', N']a]bc]]') as []]]

SELECT
 PATINDEX(N'%[^_]%', N'a_bc__') as [_]
 ,PATINDEX(N'%[^%]%', N'a%bc%%') as [%]
 ,PATINDEX(N'%[^^]%', N'a^bc^^') as [^]
 ,PATINDEX(N'%[^[]%', N'a[bc[[') as [[]
 ,PATINDEX(N'%[^]]%', N'a]bc]]') as []]]

SELECT
 PATINDEX(N'%[^_]%', N'__a_bc__') as [_]
 ,PATINDEX(N'%[^%]%', N'%%a%bc%%') as [%]
 ,PATINDEX(N'%[^^]%', N'^^a^bc^^') as [^]
 ,PATINDEX(N'%[^[]%', N'[[a[bc[[') as [[]
 ,PATINDEX(N'%[^]]%', N']]a]bc]]') as []]]

Can ^ and ] be escaped in any way?

EDIT:
I opened an idea for this as a bug.

Developer technologies | Transact-SQL
Developer technologies | Transact-SQL

A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.


2 answers

Sort by: Most helpful
  1. Erland Sommarskog 133.7K Reputation points MVP Volunteer Moderator
    2022-05-24T21:58:46.87+00:00

    My testing suggests that for the cirumflex, you get the expected result as long as you have another character in front. Olaf was half-way there, but suggested that it was escaping. It is not. So assuming that you have will have a bigger exclusion set that just ^, there should be no difficulty.

    The right bracket is more problematic, though.

    1 person found this answer helpful.

  2. Olaf Helper 47,616 Reputation points
    2022-05-24T13:33:25.88+00:00

    The characters in brackets [ ] have to be unique, and you can escape wildcards with a slash; this here works:

    SELECT PATINDEX(N'%[/^][/^]%', N'^a^bc^^') as [^]
    
    1 person found this answer helpful.

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.