【问题标题】:Splitting string by combining character groups通过组合字符组来拆分字符串
【发布时间】:2018-02-16 02:08:01
【问题描述】:

我正在使用 Excel vba 处理包含 Unicode 组合字符的字符串。我需要将字符串拆分成一个字符数组......很容易。我遇到的问题是我需要字符组。即,字符及其组合字符。如何使用 Excel vba 将字符串拆分为字符组 + 组合字符?

【问题讨论】:

  • Regex 我猜它是否是模式匹配...如果您发布示例字符串和预期输出会更有用。

标签: excel vba unicode


【解决方案1】:

VBA 没有直接功能来处理您希望的组合字符。相反,您将不得不使用一些代码来解决问题。事实上,这不是 VBA 特有的问题,请阅读https://eev.ee/blog/2015/09/12/dark-corners-of-unicode/#combining-characters-and-character-width

以下代码将尝试处理最常见的组合字符问题,并且与变音符号有关(变量 unicode() 将存储您需要的拆分后的 unicode 字符串)

当然,组合字符可能会远离标记,例如作为唯一字母的 ae 或也可以写为 ss 的 ß。

Sub Test()
    Dim r As Range
    Set r = ActiveSheet.Range("A1")
    
    ' Set some combined chars in A1 cell
    r = "a" + ChrW(&H300)
    r = r + "e" + ChrW(&H301)
    r = r + "i" + ChrW(&H305)
    r = r + "o" + ChrW(&H300)
    r = r + "u" + ChrW(&H300)
    

    ' Store the combined chars from cell A1 to str
    Dim str As String
    str = r
    ' Length, counting the individual characters in string
    Dim strLen As Integer
    strLen = Len(str)
    
    
    ' Each element in unicode() will contain combined chars
    Dim unicode() As String
    ReDim unicode(strLen)
    
    ' Length, counting the combined characters in string
    Dim unicodeLength As Integer
    unicodeLength = 0
    
    
    ' Split str into unicode()
    Dim char As Integer
    For i = 1 To strLen
        char = AscW(Mid(str, i, 1))
        
        unicode(unicodeLength) = unicode(unicodeLength) + ChrW(char)
        
        If i < strLen Then
            'If it is not the last char, check if
            'the following char is a combining diacritical mark
            'and if so, do not increment the length
            char = AscW(Mid(str, i + 1, 1))
            If Not (char >= &H300 And char <= &H36F) Then
                unicodeLength = unicodeLength + 1
            End If
        Else
            unicodeLength = unicodeLength + 1
        End If
    Next i
    
    
    ' Fill B column with 1 combined char per row
    For i = 1 To unicodeLength
        ActiveSheet.Range("B" & i) = unicode(i - 1)
    Next i
End Sub

这段代码没有考虑三个主要的事情:

  1. 除了(U+0300 到 U+036F)之外,还有更多(稀有)unicode 字符
  2. 一些变音符号(如从 U+035C 到 U+0362 的那些)将两个字符连接在一起,即 a͜b "a" + ChrW(&amp;H35C) + "b"。在这种情况下,您将不得不编写一些附加条件。
  3. 如果有一些变音符号,unicode() 数组中会有空格。在这种情况下,您必须使用ReDim PreserveunicodeLength 来释放一些空间,或者使用unicodeLength 作为您的上限。

更多信息 https://en.wikipedia.org/wiki/Combining_Diacritical_Marks

组合变音符号 (0300–036F),从 1.0 版开始,与 后续版本中的修改降至 4.1

组合变音符号扩展 (1AB0–1AFF),版本 7.0

组合变音符号补充 (1DC0–1DFF),版本 4.1 到 5.2

组合符号的变音符号 (20D0–20FF),从 1.0 版开始,经过修改 在后续版本低至 5.1

结合半分 (FE20–FE2F),版本 1.0,在后续版本中进行修改,直至 8.0

【讨论】:

  • 不回答我的问题...循环遍历每个字符。组合字符分开处理。我需要在循环中将字符组合在一起。
猜你喜欢
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 2014-07-26
  • 2011-09-24
  • 2016-04-28
相关资源
最近更新 更多