标题:分享:截取字N长度的字符串
只看楼主
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
结帖率:98.96%
已结贴  问题点数:10 回复次数:28 
分享:截取字N长度的字符串

CLEAR
Str1 = "12345人发可个方和方经品他三方登山泛水多福多寿辅导费对方012345678901nLen1-1456789"

? CutStr(str1,31)
? CutStr(31,31)

*!* 截取 N 长度的字符串,中英文通杀

FUNCTION CutStr(cStr1,nLen1)
LOCAL N1,cStr2
*!* 处理参数
IF TYPE("cStr1") # "C"
   IF  EMPTY(cStr1)
       cStr1 = ""
   ELSE
       cStr1 = ALLTRIM(TRANSFORM(cStr1))
   ENDIF
ENDIF
N1 = LEN(cStr1)
IF TYPE("nLen1") # "N"
   nLen1 = N1
ELSE
   IF nLen1 > N1
      nLen1 = N1
   ENDIF
ENDIF
   
if N1>nLen1
   LOCAL i,Nm,ary[nLen1]
   Nm=1
   FOR i=1 TO nLen1
       IF ASC(SUBSTR(cStr1,i,1))>126
          ary[i]=Nm
          Nm=Nm+1
       ELSE
          ary[i]=0
       ENDIF
   ENDFOR
            
   IF ASC(substr(cStr1,nLen1,1)) > 126
      IF ary(nLen1)>0 and MOD(ary(nLen1),2)=0
         cStr2=SUBSTR(cStr1,1,nLen1)
      ELSE
         cStr2=SUBSTR(cStr1,1,nLen1-1)
      ENDIF
   ELSE  
      cStr2=SUBSTR(cStr1,1,nLen1)

   ENDIF
ELSE
   cStr2 = cStr1   
ENDIF
RETURN cStr2
ENDFUNC
收到的鲜花
  • tlliqi2017-02-24 19:02 送鲜花  10朵   附言:谢谢
搜索更多相关主题的帖子: 字符串 登山 
2017-02-24 17:32
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:5 
关键是判断第N个字符是完整字符还是双字节字符的左半个字符,如果是双字节字符的左半个字符,取N-1或N+1字符即可。

[此贴子已经被作者于2017-2-24 17:44编辑过]


坚守VFP最后的阵地
2017-02-24 17:42
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
得分:0 
谢谢
2017-02-24 19:01
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:5 
可否这样:先计数后截取,单字节字符计1,双字节字符计2。
如:
FUNCTION _CutStr(cStr,nLen)
    LOCAL nCount
    nCount = 0
    DO WHILE nCount<nLen
        nCount = nCount + IIF(ISLEADBYTE(SUBSTR(cStr,nCount+1,1)), 2, 1)
    ENDDO
    RETURN LEFT(cStr,nCount)
ENDFUNC

收到的鲜花
  • mywisdom882017-02-24 21:13 送鲜花  10朵   附言:真简洁
2017-02-24 20:18
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
以下是引用吹水佬在2017-2-24 20:18:14的发言:

可否这样:先计数后截取,单字节字符计1,双字节字符计2。
如:
FUNCTION _CutStr(cStr,nLen)
    LOCAL nCount
    nCount = 0
    DO WHILE nCount
吹版,你知道的函数真多阿。你的代码够简洁的。。。
不过,我和你的,结果有点出入,当遇到中文时,我取的是比N-1,你的是N+1
不知道是N-1好还是N+1好

[此贴子已经被作者于2017-2-24 21:19编辑过]

2017-02-24 21:14
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
回复 5楼 mywisdom88
无所谓,双字节字符的一半是取是舍意义也差不多。
2017-02-24 21:57
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
*优化1楼后
CLEAR
Str1 = "123456人发可个方和方经品他三方登1山泛水多福多寿辅导费对方01234567890"

? CutStr(str1,31,0)
? CutStr(str1,31,1)

FUNCTION CutStr(cStr1,nLen1,nAdd)
LOCAL N1,cStr2

*!* 强行将参数值转换为字符串,并去掉字符串右边的空格
cStr1 = RTRIM(TRANSFORM(cStr1))

*!* 长度参数错误或者大于字符串长度,取字符串最大长度
N1 = LEN(cStr1)
nLen1 = IIF(TYPE("nLen1") # "N",N1,IIF(nLen1>N1,N1,nLen1))

*!* 截取的最后一个字符是半个双字节时,是舍去还是保留
nAdd = IIF(TYPE("nAdd") # "N",0,IIF(nAdd = 1,1,0))

if N1 > nLen1
   LOCAL i,nCount
   nCount = 0
   *!* 计算字符是双字节还是单字节,是第1位还是第2位
   FOR i=1 TO nLen1
       IF ISLEADBYTE(SUBSTR(cStr1,i,1)) = .T. &&判断双字节时计数 +1
          nCount = nCount + 1
       ENDIF
   ENDFOR

   IF ISLEADBYTE(SUBSTR(cStr1,i,1)) = .T. &&判断是不是双字节
      IF MOD(nCount,2)=0 &&判断是否双字节的第2位
         cStr2=SUBSTR(cStr1,1,nLen1)
      ELSE
         cStr2=IIF(nAdd = 0,SUBSTR(cStr1,1,nLen1-1),SUBSTR(cStr1,1,nLen1+1))
      ENDIF
   ELSE  
      cStr2=SUBSTR(cStr1,1,nLen1)
   ENDIF
ELSE
   cStr2 = cStr1   
ENDIF

RETURN cStr2
ENDFUNC


[此贴子已经被作者于2017-2-24 23:49编辑过]

2017-02-24 23:02
qingfameng
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:35
帖 子:964
专家分:3019
注 册:2010-2-6
得分:0 
截取‘混杂字符’的长型字串,个人认为没这么复杂(抱歉!只是个人意见!)。即:不需要作判断'单双字节',采用的是直接固定截取,清除,再截取方式。比较简单。在sql server 表中,从TEXT 字段内取出的文章,里面是什么样的字符都有,我就是这样分段的,现在也一直实际用着。(代码后续) ....



2017-02-24 23:27
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
以下是引用qingfameng在2017-2-24 23:27:44的发言:

截取‘混杂字符’的长型字串,个人认为没这么复杂(抱歉!只是个人意见!)。即:不需要作判断'单双字节',采用的是直接固定截取,清除,再截取方式。比较简单。在sql server 表中,从TEXT 字段内取出的文章,里面是什么样的字符都有,我就是这样分段的,现在也一直实际用着。(代码后续) ....
 
 
 
中文版的 sql server ,是用nvarchar来保存的,无论是取多少个,都不会有半个字符的,但在VFP中取,就会出现半个字符
2017-02-24 23:51
kiff
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广州
等 级:贵宾
威 望:46
帖 子:756
专家分:2531
注 册:2013-1-30
得分:0 
Str1 = "12345人发可个方和方经品他三方登山泛水多福多寿辅导费对方012345678901nLen1-1456789"
nLen1=32
?SUBSTRC(LEFT(str1,nLen1),1)
2017-02-25 11:36



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-474515-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.621488 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved