【问题标题】:How to split an unicode-string to readable characters?如何将 unicode 字符串拆分为可读字符?
【发布时间】:2021-10-16 20:23:11
【问题描述】:

我有一个 VBA 公式函数来拆分字符串并在每个字符之间添加空格。它仅适用于 Ascii 字符串。但我想为泰米尔语做同样的事情。由于它是 Unicode,因此结果不可读。它甚至拆分了在泰米尔语/印地语/加拿大语/马拉雅拉姆语/全印度语言中不应分开的辅助字符、上点、前缀、后缀辅助字符。那么,如何编写一个函数将泰米尔语单词拆分为可读字符。

Function AddSpace(Str As String) As String
    Dim i As Long
    For i = 1 To Len(Str)
        AddSpace = AddSpace & Mid(Str, i, 1) & " "
    Next i
    AddSpace = Trim(AddSpace)
End Function

添加空间不是这个问题的重点。将 Unicode 字符串从这些语言中的任何一种拆分为一个数组是必需的。

例如,单词“பார்த்து”应分隔为“பா ர் த் து”,而不是“ப ா ர ் த ் த ு”。如您所见,前两个字母“பா”(ப + ா)组合在一起。如果我尝试在它们之间手动放置一个空格,我无法在任何文字处理器中这样做。如果要测试,请将其放在记事本中,并在每个字符之间添加空格。它不允许您分开为(“ப ா”)。所以“பார்த்து”应该分开为“பா ர் த் து”。在类似泰米尔语的语言中,这是正确的分隔。这是我在 VBA 中努力实现的目标。

泰米尔语的字符代码表是here。 泰米尔语/印地语/许多印度语言有(1)辅音,(2)独立元音,(3)从属元音符号,(4)两部分从属元音符号。在这 4 种类型中,前两种是一个单独的字母,它们没有问题。但最后2个是依赖的,它们不应该与其联合特征分开。例如字母 பா (ப + ் ),它包含一个独立 (ப) 和一个从属 (ா) 字母。

如果这些信息还不够,请评论我应该发布更多内容。

(注意:在 C#.Net 中可以使用 @Codo 的 MS link 中的代码)

【问题讨论】:

  • 我没有办法测试,但请查看StrConvTHIS。该问题的答案使用 StrConv 将字符串拆分为数组。然后你可能循环数组。
  • edit 分享您的问题minimal reproducible example。你怎么调用AddSpace函数;特别是,它提供的论点来自哪里? Afaik,VBA 在内部使用 UCS-2?
  • @ScottCraner 我已经浏览了链接,现在再次将单词分成字节,而不是泰米尔语或类似语言中的字符串中的可读字符。
  • @JosefZ 我想,我已经给出了可重现的例子。我将泰米尔语单词放在 Excel 单元格 A1 中,并输入我提供的公式 =AddSpace("A1"),它适用于 Anscii,不适用于泰米尔语。我无法编写将泰米尔语单词分成可读字母的函数,我不知道。
  • 泰米尔语有将“字符”组合成“图形符号”的复杂规则,Unicode 选择的表示也无济于事。为了实现您的目标,您将需要知道如何将 Unicode 代码点组合成字素簇的代码。这将在 .NET (docs.microsoft.com/en-us/dotnet/api/…) 中可用,但必须在 VBA 中从头开始实现。

标签: vba string unicode char


【解决方案1】:

您可以将字符串分配给 Byte 数组,这样以下可能会起作用

Dim myBytes as Byte
myBytes = "Tamilstring"

为每个字符生成两个字节。然后,您可以创建一个大小是第一个字节数组两倍的第二个字节数组,方法是使用 space$ 创建一个合适的字符串,然后使用 for 循环(步骤 4)一次将两个字节从第一个数组复制到第二个数组。最后,将字节数组分配回字符串。

【讨论】:

  • 我在我的问题中添加了更多信息。泰米尔语 unicode 可能使用 2 个字节。但是一个可读的字母并不总是一个 2 字节。它可能是一个组合,我已经添加了这个信息。请检查。
  • myBytes = StrConv(TextFromCellHavingTamilWord, vbFromUnicode, 1097) '1097 是泰米尔语的语言环境 id,输出是一个奇怪的符号 myBytes(x) = "�"
【解决方案2】:

您遇到的问题是您正在寻找 Unicode 所称的扩展字形集群。

对于一个 Unicode 兼容的正则表达式引擎,它只是 /\X/

不确定你是如何在 VBA 中做到这一点的。

【讨论】:

    【解决方案3】:

    参考@ScottCraner 在 cmets 中提到的linkCharacter code for Tamil

    检查单元格A2中的结果并以黄色突出显示的是在DepVow字符串中使用的相关元音符号

    Sub Split_Unicode_String()
    'https://stackoverflow.com/questions/68774781/how-to-split-an-unicode-string-to-readable-characters
    Dim my_string As String
        'input string
    Dim buff() As String
        'array of input string characters
    Dim DepVow As String
        'Create string of Dependent vowel signs
    Dim newStr As String
        'result string with spaces as desired
    Dim i As Long
    
    my_string = Range("A1").Value
    
    ReDim buff(Len(my_string) - 1) 'array of my_string characters
    For i = 1 To Len(my_string)
        buff(i - 1) = Mid$(my_string, i, 1)
        Cells(1, i + 2) = buff(i - 1)
        Cells(2, i + 2) = AscW(buff(i - 1)) 'used this for creating DepVow below
    Next i
    
    'Create string of Dependent vowel signs preceded and succeeded by comma
    DepVow = "," & Join(Array(ChrW$(3006), ChrW$(3021), ChrW$(3009)), ",")
    newStr = ""
    
    For i = LBound(buff) To UBound(buff)
        If InStr(1, DepVow, ChrW$(AscW(buff(i + 1))), vbTextCompare) > 0 Then
            newStr = newStr & ChrW$(AscW(buff(i))) & ChrW$(AscW(buff(i + 1))) & " "
            i = i + 1
        Else
            newStr = newStr & ChrW$(AscW(buff(i))) & " "
        End If
    Next i
    
    'result string in range A2
    Cells(2, 1) = Left(newStr, Len(newStr) - 1)
    
    End Sub
    

    【讨论】:

    • 创建第一个循环以显示 my_string 字符的结果数组,因此可以通过检查 DepVow 中的 Mid$(my_string, i+1, 1) 来进一步改进以适应一个循环
    【解决方案4】:

    试试下面的算法。这会将所有标记字符与字母字符连接起来。

    redim letters(0) 
    For i=1 To Len(Str) 
    If ascW(Mid(Str,i,1)) >3005 And ascW(Mid(Str,i,1)) <3022 Then 
    letters(UBound(letters)-1) = letters(UBound(letters)-1)+Mid(Str,i,1) 
    Else REDIM PRESERVE
    letters(UBound(letters) + 1) 
    letters(UBound(letters)-1) = Mid(Str,i,1)
    End If 
    Next
     
    MsgBox(join(letters, ", "))'return பா, ர், த், து,
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      • 2013-09-13
      • 2019-05-12
      相关资源
      最近更新 更多