【问题标题】:Tokenize Myanmar names, typed using Pyidaungsu Unicode font, in MS Excel, using VBA UDF使用 VBA UDF 在 MS Excel 中标记缅甸名称,使用 Pyidaungsu Unicode 字体键入
【发布时间】:2022-01-26 04:26:36
【问题描述】:

我到处寻找一种方法来对缅甸名称进行排序,用 Pyidaungsu unicode 字体输入,在 MS Excel 中按最后一个辅音。

使用 Excel 的内置公式/函数,用英语做同样的事情相对容易。
但是在缅甸语中很难找到缅甸名字,因为缅甸名字在每个单词之间不需要空格,而且名字、中间名和姓氏并不像例如。约翰·W·史密斯。

在缅甸名称中,例如。 အောင်မြင့်မြတ်=Aung Myint Myat,如果用缅甸字体书写,则没有明确的名字/姓氏,也不需要空格!

因此,很难找到每个单词之间的单词边界,即အောင် 开始和结束以及 မြင့် 开始和结束等等!

所以我需要一个 VBA UDF 来标记缅甸名称!

【问题讨论】:

    标签: excel vba unicode user-defined-functions


    【解决方案1】:

    经过大量搜索和阅读NLP文献,其中很多我不是很了解,我意识到缅甸字体Pyidaungsu的名称有一个字符绑定方法,将所有缅甸字符:辅音和变音符号绑定在一起比如:每个单词的辅音在前,然后是变音符号(或者我可能对它的称呼有误)
    因此,如果我可以在每个辅音之前放置一个分隔符/分隔符,我应该能够标记每个单词!
    幸运的是,它可以帮助我编写 VBA 代码,例如:

    Const kagyi = 4096
    Const ah = 4129 '+9 to include ou
    Const athat = 4154
    Const shiftF = 4153 'for typing something under something
    Const witecha = 4140
    Const moutcha = 4139
    
    'Return a tokenized Myanmar String
    Function MMRTokenizer(target As Range) As String
    Dim ch As String
    Dim returnString As String
    Dim charCounter As Integer
    Dim previousChIsAthat As Boolean
    Dim shiftFfound As Boolean
    Dim previousCharAt As Long
         If target.Cells.CountLarge > 1 Then MMRTokenizer = ">1Cell!": Exit Function
         returnString = "": previousChIsAthat = False: shiftFfound = False: previousCharAt = Len(target.Value) + 1
         If target.CountLarge = 1 Then
             If target.Value <> "" Then
                 For charCounter = Len(target.Value) To 1 Step -1
                     ch = Mid(target.Value, charCounter, 1)
                     If AscW(ch) <> shiftF Then
                         If Not shiftFfound Or AscW(ch) = athat Then
                             If AscW(ch) <> athat Then
                                 If AscW(ch) >= kagyi And AscW(ch) < ah + 9 Then
                                     If Not previousChIsAthat Then
                                         returnString = Mid(target.Value, charCounter, previousCharAt - charCounter) & IIf(Len(returnString) > 0, "|", "") & returnString
                                         previousCharAt = charCounter
                                     Else
                                         previousChIsAthat = False
                                     End If
                                 Else
                                     If AscW(ch) = witecha Or AscW(ch) = moutcha Then
                                         previousChIsAthat = False
                                     End If
                                 End If
                             Else
                                 previousChIsAthat = True
                                 If shiftFfound Then shiftFfound = False
                             End If
                         Else
                             shiftFfound = False
                             If previousChIsAthat Then previousChIsAthat = False
                         End If
                     Else
                         shiftFfound = True
                     End If
                 Next charCounter
             End If
         End If
         MMRTokenizer = returnString
     End Function
    

    理论上,这应该很简单,因为我没有使用任何 NLP 或 ML 方法,而只是使用了一些字符串操作。
    我从右边取出名字/单词的每个字符(从左边开始可能没问题)然后向左走直到我找到一个辅音并在它的左边放置一个分隔符/定界符然后继续向左重复相同的过程,直到到达最左边的字符。

    这里需要注意的是,有时可能会有辅音,在缅甸语中,辅音是辅音和变音符号(很常见的行为)组合的一部分,例如。在 အောင်=‌ေ+အ+ ာ+င+် 虽然看起来像那样,但 Pyidaungsu 字体将其绑定为 အ+‌ေ+ာ+င+် ,如果使用 Windows 缅甸语键盘输入(可视顺序),最右边的两个,င+်,其中င=辅音称为nga,်=变音符号称为Athat。
    在这种情况下,我们只是跳过那个叛变的辅音(如果我们在它的右边遇到那个特定的变音符号),因为根据缅甸语的拼写方式,它不应该被计算在内。

    我使用了chrWascW 函数,因为无法在 VBIDE 中呈现缅甸字体(即使在区域设置中进行了调整后),因此,我不得不检查 unicode 字符代码,而不是直接比较缅甸字符。

    以上只是整个事情如何运作的要点。
    更多详情请访问我的GitHub

    在我们像上面那样进行标记之后,我们得到了类似的东西:အောင်|မြင့်|မြတ် 现在很容易使用内置 Excel 公式拆分或反转为 မြတ်|မြင့်|အ် 现在可以这样排序最后一个字(或姓氏)或分成姓氏/名字的基础!

    注意:整个标记化过程可以/可以通过在 Excel 中使用各种公式的组合来实现,因为没有什么是不可能的,尤其是在 Excel365 中(数组只是在没有 CSE 的情况下溢出),恕我直言,但是,我希望在这种情况下,我们可以很容易地看到收益与复杂性和工作量的对比。

    我在此承认,上面的代码可能不是最优雅的,但是,它是一个经过验证的概念验证工具,因此使用它需要您自担风险,但可以向我提供的 GitHub 报告错误以上。

    【讨论】:

      猜你喜欢
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      相关资源
      最近更新 更多