sql 2005 中英文混合的字符串截取函数

  做网站的时候经常会碰到要截取字符串的情况。但Len函数不管是中文字符,还是英文字符,统统按一个单位来计算,由于一个中文字符的宽度通常是两个英文字符宽度,在中英文混合的情况下字符串实际占用的宽度就不好计算了,如果按照Len函数计算的长度来截取字符串截出来的效果就会长短不一,下面是按照一个汉字相当于两个英文字符来计算字符串长度截取字符串的数据库函数代码

CREATE FUNCTION [dbo].[FNC__CUT_STRING_BY_WIDTH_EN_CN](
@Content nvarchar(4000),
@Size int
)
RETURNS nvarchar(4000)
AS
BEGIN  
--   SET @Content = N'Office of Commissioner Insurance - Establishment of an Independent Insurance Authority in Hong Kong (2009)'
--   SET @Size = 26
SET @Content = LTRIM(RTRIM(REPLACE( REPLACE(@Content,CHAR(10),' '),CHAR(13),' ')))
if @Size > 0 AND @Size < 2 * LEN (@Content)
begin
   declare @Pos INT --Current pointer
   DECLARE @sPos INT --Current stay pointer
   DECLARE @PrePos INT --Previous stay pointer
   declare @tempS nvarchar(4)
   DECLARE @tempNextS nvarchar(4)
   declare @tempSize INT
   DECLARE @unicodeS INT
   DECLARE @unicodeNextS INT
   set @Pos = 1
   set @sPos = 0
   SET @prePos = 0
   SET @tempS = N''
   SET @tempNextS = N''
   SET @tempSize = 0
  
   WHILE @Pos < len(@Content)
   BEGIN
    IF @tempSize < @Size
    BEGIN
     SET @tempS = SUBSTRING(@Content,@Pos,1)
     SET @tempNextS = SUBSTRING(@Content,@Pos+ 1,1)
     SET @unicodeS = UNICODE(@tempS)
     SET @unicodeNextS = UNICODE(@tempNextS)

     IF @unicodeS > 254
     BEGIN
      SET @tempSize = @tempSize + 2
      SET @sPos = @Pos         
     END
     ELSE
     BEGIN     
      SET @tempSize = @tempSize + 1
     
      -- Do not turncate the word just length as @Size by add symbol before and after the word
      IF @unicodeS < 48 OR (@unicodeS > 57 AND @unicodeS < 65) OR (@unicodeS > 90 AND @unicodeS < 97) OR @unicodeS > 122
       OR @unicodeNextS < 48 OR (@unicodeNextS > 57 AND @unicodeNextS < 65) OR (@unicodeNextS > 90 AND @unicodeNextS < 97) OR @unicodeNextS > 122
      BEGIN
       SET @sPos = @Pos
      END
     
     END    
    END
   
    IF @tempSize > @Size - 2 AND @unicodeNextS > 254 -- if next letter is Chinese then turncate the string
    BEGIN
     SET @tempSize = @Size
     SET @sPos = @Pos
    END
    ELSE IF @tempSize = @Size AND @PrePos = @sPos -- else if the English word length is large than the @Size then turncate the word
    BEGIN
     SET @sPos = @Pos
    END
   
    IF @tempSize >= @Size
    BEGIN
     set @Content = left(@Content, @sPos)
--     +'@'
        + nchar(13)
      + right(@Content, len(@Content) - @sPos)
     SET @tempSize = 0
     SET @PrePos = @sPos
     set @Pos = @sPos + 1
    END
    set @Pos = @Pos + 1
    SET @unicodeS = 0
    SET @unicodeNextS = 0
   END
  
END

RETURN @Content
END

  函数中逐个字符扫描字符串,以unicode(@tempS) > 254 为介判断是否为中英文,设定英文字符长为一byte长度,中文为两byte长度. 在英文字符串中,正常情况下, 是不允许把一个单词截断的.此时就需要考虑一个单词的截断情况,提前截断字符串

 

test :

PRINT dbo.FNC__CUT_STRING_BY_WIDTH_EN_CN(N'of Commissioner Insurance - Establishment of an Independent Insurance Authority in Hong Kong (2009)',26)

---------------------------------------------

of Commissioner Insurance
- Establishment of an
Independent Insurance
Authority in Hong Kong (
2009)

 

PRINT dbo.FNC__CUT_STRING_BY_WIDTH_EN_CN(N'Len函数不管是中文字符,还是英文字符,统统按一个单位来计算,由于一个中文字符的宽度通常是两个英文字符宽度',26)

---------------------------------------------

Len函数不管是中文字符,还
是英文字符,统统按一个单位
来计算,由于一个中文字符的
宽度通常是两个英文字符宽度

 

PRINT dbo.FNC__CUT_STRING_BY_WIDTH_EN_CN(N'Grove Tool Kit 是针对Grove Develop Component提供的一套.NET Develop Environment的外接程序 ,能够帮助预览或生成依赖于Grove组件的可重用代码',25)

---------------------------------------------

Grove Tool Kit 是针对
Grove Develop Component提
供的一套.NET Develop
Environment的外接程序 ,
能够帮助预览或生成依赖于
Grove组件的可重用代码

 

posted @   二水四夕  阅读(1377)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示