Technical Article

Use of regular expressions in TSQL -- version 2

,

This script creates 2 new system functions

******************************************

NEW:

1. functions will be case sensitive if database is

2. Replace all or only first occurence

******************************************

fn__regexp_test(@String,@Pattern) returns int

execute the method test(@String) on the regular expressions @Pattern

returns :

0 : no match

1 : match

null : one of the parameters was null

anything else : error from sp_OA procedure

fn__regexp_replace(String,@Pattern,@Replace,@Global) returns varchar

execute the method Replace(@String,@Replace) on the regular expressions @Pattern

Global = 1 ( Default ) replaces all occurences, Global = 0 only the first occurance

returns :

null on failure of an sp_OA procedure

null if one of the paremeters is null

the result of the replace

/*
**Author : Bert De Haes
**Date : 2004-04-06
**
**This script creates 2 new system functions :
**
**fn__regexp_test(@String,@Pattern) returns int
**execute the method test(@String) on the regular expressions @Pattern
**returns :
**0 : no match
**1 : match
**null : one of the parameters was null
**anything else : error from sp_OA procedure
**
**fn__regexp_replace(String,@Pattern,@Replace,@Global) returns varchar
**execute the method Replace(@String,@Replace) on the regular expressions @Pattern
**Global = 1 ( Default ) replaces all occurences, Global = 0 only the first occurance
**returns :
**null on failure of a sp_OA procedure
**null if one of the paremeters is null
**the result of the replace
**
*/go
set nocount on
go
use master
go
sp_configure 'allow updates',1
go
RECONFIGURE WITH OVERRIDE
go
if exists ( select 1 from sysobjects where name = 'fn__regexp_test' )
drop function system_function_schema.fn__regexp_test
go
create function system_function_schema.fn__regexp_test
(
@String varchar(4000),
@Pattern varchar(255)
)  
returns int -- 0 if no match, 1 if match, other values on failure
as  
begin  
declare @ret int, @ret2 int  
declare @regexp int  
declare @result int 
declare @IgnoreCase int

-- get IgnoreCase form current collation settings
set @IgnoreCase = case when 'x' = 'X' then 1 else 0 end

if @String is null or @Pattern is null return null

-- create object vbscript.regexp. return errorcode on failure
exec @ret = sp_OACreate 'VBScript.RegExp', @regexp output  
if @ret <> 0 return case when @ret = 1 then -1 else @ret end

-- set property Pattern. go to FINI on failure ( will destroy object )
exec @ret = sp_OASetProperty @regexp, 'Pattern', @Pattern  
if @ret <> 0 goto FINI

-- set property IgnoreCase. go to FINI on failure ( will destroy object )
exec @ret = sp_OASetProperty @regexp, 'IgnoreCase', @IgnoreCase
if @ret <> 0 goto FINI

-- exec method Test. go to FINI on failure
exec @ret = sp_OAMethod @regexp, 'Test', @result output, @String  
if @ret <> 0 goto FINI

FINI:
-- destroy created object
exec @ret2 = sp_OADestroy @regexp  

-- if failure before destroy, return failure status
if @ret  <> 0 return case when @ret  = 1 then -1 else @ret  end
-- if failure on destry, return destroy failure status
if @ret2 <> 0 return case when @ret2 = 1 then -1 else @ret2 end

-- return the result
return @result 
end  
go
if exists ( select 1 from sysobjects where name = 'fn__regexp_replace' )
drop function system_function_schema.fn__regexp_replace
go
create function system_function_schema.fn__regexp_replace
(
@String varchar(4000),
@Pattern varchar(255),
@Replace varchar(4000),
@Global bit = 1
)  
returns varchar(4000)  -- replaced string on success, null on failure
as  
begin  
declare @ret int, @ret2 int
declare @regexp int  
declare @result int
declare @IgnoreCase int

-- get IgnoreCase form current collation settings
set @IgnoreCase = case when 'x' = 'X' then 1 else 0 end 

-- return null if one of the parameters is null
if @String is null or @Pattern is null or @Replace is null return null

-- create object vbscript.regexp. return null on failure
exec @ret = sp_OACreate 'VBScript.RegExp', @regexp output  
if @ret <> 0 return null 

-- set property Pattern. go to FINI on failure ( will destroy object )
exec @ret = sp_OASetProperty @regexp, 'Pattern', @Pattern  
if @ret <> 0 goto FINI 

-- set property IgnoreCase. go to FINI on failure ( will destroy object )
exec @ret = sp_OASetProperty @regexp, 'IgnoreCase', @IgnoreCase
if @ret <> 0 goto FINI

-- set property Global. go to FINI on failure ( will destroy object )
exec @ret = sp_OASetProperty @regexp, 'Global', @Global
if @ret <> 0 goto FINI

-- exec method Test. go to FINI on failure
exec @ret = sp_OAMethod @regexp, 'Test', @result output, @String  
if @ret <> 0 goto FINI

-- if no match : done ( no replace needed )
if @result <> 1 goto FINI

-- exec method Replace. go to FINI on failure
exec @ret = sp_OAMethod @regexp, 'Replace', @String output, @String, @Replace  
if @ret <> 0 goto FINI

FINI:
exec @ret2 = sp_OADestroy @regexp 

-- if failure, return null
if @ret <> 0 return null  
-- if failure for destroy, return null
if @ret2 <> 0 return null

-- return replaced string
return @String  
end  
go
grant exec on system_function_schema.fn__regexp_test to public
grant exec on system_function_schema.fn__regexp_replace to public
go
sp_configure 'allow updates',0
go
RECONFIGURE WITh OVERRIDE
go
print 'test fn__regexp_test'
go
if object_id('tempdb..#fn__regexp_test') is not null drop table #fn__regexp_test
create table #fn__regexp_test (String varchar(50),Pattern varchar(50))
insert #fn__regexp_test values ( 'This is a test' , '^T.* is +.*' )
insert #fn__regexp_test values ( 'This is a test' , '^T.* is  +.*' )
insert #fn__regexp_test values ( 'This is a test' , '^t.* is +.*' )
select*,fn__regexp_test = fn__regexp_test(String,Pattern) from #fn__regexp_test
drop table #fn__regexp_test
go
print 'test fn__regexp_replace'
go
if object_id('tempdb..#fn__regexp_replace') is not null drop table #fn__regexp_replace
create table #fn__regexp_replace (String varchar(50),Pattern varchar(50),Replace varchar(50))
insert #fn__regexp_replace values ( 'This isis a test' , ' is[^ ]*' , ' is' )
insert #fn__regexp_replace values ( 'This is a test' , 'SQL' , 'sql' )
insert #fn__regexp_replace values ( 'This is a test' , 'This' , 'this' )
insert #fn__regexp_replace values ( 'This is a test' , 'THIS' , 'this' )
insert #fn__regexp_replace values ( 'This is a test' , 'is' , 'IS' )
insert #fn__regexp_replace values ( '016/68.15.27'   , '[^0-9]','' )
select*,Global=0,fn__regexp_replace = fn__regexp_replace(String,Pattern,Replace,0) from #fn__regexp_replace
select*,Global=1,fn__regexp_replace = fn__regexp_replace(String,Pattern,Replace,1) from #fn__regexp_replace
drop table #fn__regexp_replace
go

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating