设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

123下一页
返回列表 发新帖
查看: 7487|回复: 20
打印 上一主题 下一主题

[其它] 【已解决】如何将字符串按定长字节分割成多个字符串?

[复制链接]
跳转到指定楼层
1#
发表于 2014-4-25 21:57:12 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 玉树TMD临风 于 2014-4-26 11:36 编辑

有个字符串A,里面有中、英文,中文算2个字符,英文算一个字节。

现在想将字符串按字节分割,用"\"隔开,如果分割处刚好是个汉字各占一半,那这个汉字就算到下个分割后的字符串,缺的那个字节用空格顶上。

比如:
字符串A="我1人2年吃了3斤油“,要求按3个字节分割。

正确结果是:“我1\人2\年 \吃 \了3\斤 \油 ",因为”我“的字节长度是2,”1“的字节长度是1,加起来刚好是3,以此类推。。。

这个看起来简单,可我弄了2天没弄好,特来求助。

已搞定,谢谢各位,附上源码:

Function test(zf As Variant, n As Integer)

On Error Resume Next        '当N为某此数值时,下面的I+1会超出字符长度而报错

Dim tmp As String

Dim m As Integer, i As Integer

For i = 1 To Len(zf)

tmp = tmp & Mid(zf, i, 1)

Select Case Asc(Mid(zf, i, 1))

Case Is > 0

a = a + 1           '英文字符

Case Else

a = a + 2           '中文字符

End Select

If a = n Then test = test & tmp & "\": tmp = "": a = 0

If a = n - 1 Then If Asc(Mid(zf, i + 1, 1)) < 0 Then test = test & tmp & " \": tmp = "": a = 0

If i = Len(zf) And a < n - 1 And a <> 0 Then test = test & tmp & Space(n - a) & "\": a = 0
'
最后一段如果不够字节长度N时

Next i

End Function


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享分享 分享淘帖 订阅订阅
21#
发表于 2014-4-26 15:11:43 | 只看该作者
我不是提供了四个方法,你都 试试,
目前最完美的解决方案是,算法3了,不管准确度还是速度,你就直接用这个。

其实判定单双字节,本身就不是个很严谨的问题(因为它与你的字体有一定关系),只不过在一些特定环境却有一定用处。
20#
 楼主| 发表于 2014-4-26 15:03:14 | 只看该作者
wang1999 发表于 2014-4-26 14:38
这个算法有些情况下是有问题的
用你的这个算法试试下面的字符串
    Str = "ΑΒΓαβγ" '希腊字符

不过我的代码把所有英文字符以外的都算双字节,你这些字母我也不知道是单还是双,所以用我的代码是按双字节算出来的
19#
 楼主| 发表于 2014-4-26 14:59:48 | 只看该作者
wang1999 发表于 2014-4-26 14:38
这个算法有些情况下是有问题的
用你的这个算法试试下面的字符串
    Str = "ΑΒΓαβγ" '希腊字符

我这代码算出来是12,应该是多少?
18#
发表于 2014-4-26 14:38:36 | 只看该作者
玉树TMD临风 发表于 2014-4-26 14:26
转换成字节问题不大,用下面这个就可以了,现在遇到新问题,开新贴问。
For i = 1 To Len(zf)
Select  ...

这个算法有些情况下是有问题的
用你的这个算法试试下面的字符串
    Str = "ΑΒΓαβγ" '希腊字符


17#
发表于 2014-4-26 14:28:46 | 只看该作者
'算法三     直接操作对比Unicode码
Function LenDB(Str As String) As Long
    Dim i As Long, lngLenB As Long
    Dim abytStr() As Byte
    Const DoubleByte As Byte = &H30
    abytStr = Str
    lngLenB = LenB(Str)
    For i = 1& To lngLenB Step 2&
        If abytStr(i) < DoubleByte Then
            lngLenB = lngLenB - 1&
        End If
    Next
    LenDB = lngLenB
End Function

算法三应该甩开算法StrConv几条街了
16#
 楼主| 发表于 2014-4-26 14:26:34 | 只看该作者
wang1999 发表于 2014-4-26 14:03
还有没有更快的方法呢,看着StrConv要进行一次转换真不爽!
再写一个

转换成字节问题不大,用下面这个就可以了,现在遇到新问题,开新贴问。
For i = 1 To Len(zf)
Select Case Asc(Mid(zf, i, 1))
Case Is > 0
a = a + 1           '英文字符
Case Else
a = a + 2           '中文字符
End Select
15#
发表于 2014-4-26 14:03:35 | 只看该作者
还有没有更快的方法呢,看着StrConv要进行一次转换真不爽!
再写一个
14#
发表于 2014-4-26 13:23:22 | 只看该作者
本帖最后由 wang1999 于 2014-4-26 15:01 编辑

前天听完课后,答应你回复你,可一直太忙,今天刚只有一点空,先给出代码给你。有空再深入分析吧
核心是计算中文字节长度,在VB5时代直接可以用LEN函数即可,可UNICODE就不同了。
目前我知道方法有4种,核心代码如下

算法一利用StrConv(比算法二快9倍)
'-----------------------------------------------------------------
Public Function LenEx(VarString As Variant) As Variant
'算法一
    LenEx = LenB(StrConv(VarString, vbFromUnicode))    '将Unicode转换为ANSI,然后再计算字节长度
End Function
''算法二
'Public Function LenEx1(VarString As Variant) As Variant
'    Dim lLen As Integer, i As Integer
'    LenEx1 = 0
'    lLen = Len(VarString)
'    If lLen Then                              '如长度不为零
'        For i = 1 To lLen
'            If Asc(Mid(VarString, i, 1)) < 0 Then
'                LenEx1 = LenEx1 + 2
'            Else
'                LenEx1 = LenEx1 + 1
'            End If
'        Next
'    End If
'End Function

方法四,利用 lstrlenA 函数, 等于利用VB的后台U/A转换,效率跟StrConv差不多。
13#
 楼主| 发表于 2014-4-26 11:33:23 | 只看该作者
搞了一上午终于搞定了,附上源代码:

Function test(zf As Variant, n As Integer)
On Error Resume Next        '当N为奇数时
Dim tmp As String
Dim m As Integer, i As Integer
For i = 1 To Len(zf)
tmp = tmp & Mid(zf, i, 1)
Select Case Asc(Mid(zf, i, 1))
Case Is > 0
a = a + 1           '英文字符
Case Else
a = a + 2           '中文字符
End Select
If a = n Then test = test & tmp & "\": tmp = "": a = 0
If a = n - 1 Then If Asc(Mid(zf, i + 1, 1)) < 0 Then test = test & tmp & " \": tmp = "": a = 0
If i = Len(zf) And a < n - 1 And a <> 0 Then test = test & tmp & Space(n - a) & "\": a = 0   '最后一段如果不够字节长度N时
Next i
End Function

谢谢楼上各位,如果有更简单的办法可继续讨论

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-16 06:36 , Processed in 0.089377 second(s), 34 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表