VB のたまご

作成日: 2016/08/07, 更新日: 2016/08/13


getdata と入力したら、GetData、または、getData と変換したい

  •  意味不明なタイトルから始まりましたが、自作IDEを作ってみようシリーズの続編です。 例えば、Visual Studio で、console.writeline() と入力する場合を考えてみます。 すると、入力中にインテリセンスが自動変換してくれるので、Console.WriteLine() になりますが、インテリセンスにあらがって、 C, W, L を小文字に直します。しかし、その行からカーソルが移動するタイミングで Console.WriteLine() に直されます。

  • この処理を作りたい!

  • というお話です。

  • スポンサーリンク



Pascal 形式、Camel 形式に変換する命令は無い

  •  まず私が知っているのは、String.ToUpper() と String.ToLower() です。 また、TextInfo クラスを使うことで、単語を Pascal 形式に変換してくれるみたいです。 ちなみに、Pascal 形式は、Console.WriteLine で、Camel 形式が、console.writeLine です。 (最初の単語だけ小文字、続く次の単語以降は先頭大文字)。

  • Imports System.Globalization
    
    Dim item = "Console.WriteLine()"
    
    ' 小文字
    Console.WriteLine(item.ToLower())
    
    ' 大文字
    Console.WriteLine(item.ToUpper())
    Console.WriteLine()
    
    ' 先頭大文字
    
    ' TextInfo というクラスがあるみたい
    ' インスタンスの取得方法が独特
    ' 変換したい文字列が全て大文字の場合、いったん小文字に直さないとダメくさい
    Dim ti As TextInfo = CultureInfo.CurrentCulture.TextInfo
    
    item = "Console.WriteLine()"
    Console.WriteLine(ti.ToTitleCase(item))
    
    item = item.ToUpper()
    Console.WriteLine(ti.ToTitleCase(item))
    
    item = item.ToLower()
    Console.WriteLine(ti.ToTitleCase(item))
    
    
    ' 出力結果
    console.writeline()
    CONSOLE.WRITELINE()
    
    Console.Writeline()
    CONSOLE.WRITELINE()
    Console.Writeline()
    
    
  •  事前に小文字に直さないといけない、はまだ良いとして、変換しても line は小文字のままか・・・

  • スポンサーリンク



無いなら作ろう、変換処理

  •  TextInfo を調べていたら、変換ルールがあるっぽいことが分かってきました。 と言っても詳しくは分かりませんが、例えば、スペースが間に入っている文字列は、うまく変換されています。
  • ' どうやら、スペースが間にあると後ろにある単語も変換してくれるみたい
    Console.WriteLine(ti.ToTitleCase("thisisapen."))
    Console.WriteLine(ti.ToTitleCase("this is a pen."))
    
    ' 出力結果
    Thisisapen.
    This Is A Pen.
    

  •  プログラミングに限って言えば、GetXxx, SetXxx とか、分かりやすいメソッド名の命名規則がありますよね。 このルールに従っているメソッドであれば、固定文字列にスペースを挿入しておいて、変換後にスペース除去すればできそうです。

  •  ただし、固定文字列を処理するということは力技解決になるので、つまり決められたパターンしか処理できないので、汎用化は難しいですね。。。 しかも、この場合スペースは制御文字扱いとなるので、スペース入り文字列は変換できなくなりますが、割愛します。
  • ' 作った機能のテスト
    item = "CONSOLE.WRITELINE()"
    Console.WriteLine("Normal = {0}", item)
    Console.WriteLine("PascalCase = {0}", Me.ToPascal(item))
    Console.WriteLine("CamelCase = {0}", Me.ToCamel(item))
    Console.WriteLine("")
    
    
    ' target は単語、または連続した単語のみサポートします。
    ' 文章(This is a pen.)の場合は、仕様上スペース除去してしまうので未サポートです。
    Private Function ToPascal(target As String) As String
    
        ' 小文字に変換
        target = target.ToLower()
    
        ' Pascal 変換がうまくいくように、区切りを追加
        target = Me.AddHalfSpace(target)
    
        ' 小文字にしておいて、Pascal 変換
        Dim ti As TextInfo = CultureInfo.CurrentCulture.TextInfo
        target = ti.ToTitleCase(target)
    
        ' 不要な区切りを除去
        target = Me.RemoveHalfSpace(target)
    
        Return target
    
    End Function
    
    Private Function AddHalfSpace(target As String) As String
    
        ' 判定処理をたくさん書かないと、実質使えない・・・。
        ' o - GetXxx, SetXxx, XxxInfo
        ' x - GetSetMethod, GetGetMethod, InfomationInfo, etc.
    
        'If target.StartsWith("get") Then target = target.Insert("get".Length, " ")
        'If target.StartsWith("set") Then target = target.Insert("set".Length, " ")
        'If target.EndsWith("info") Then target = target.Insert(target.LastIndexOf("info"), " ")
    
        If target.Contains("write") AndAlso Not target.EndsWith("write") Then
    
            Dim index = target.IndexOf("write") + "write".Length
            target = target.Insert(index, " ")
    
        End If
    
        Return target
    
    End Function
    
    Private Function RemoveHalfSpace(target As String) As String
        Return target.Replace(" ", String.Empty)
    End Function
    
    Private Function ToCamel(target As String) As String
    
        target = Me.ToPascal(target)
    
        ' 先頭1文字を小文字に変換
        Dim firstHalf As String = target.Chars(0).ToString().ToLower()
        Dim secondHalf As String = target.Substring(1)
        target = firstHalf & secondHalf
    
        Return target
    
    End Function
    
    
    ' 出力結果
    Normal = CONSOLE.WRITELINE()
    PascalCase = Console.WriteLine()
    CamelCase = console.WriteLine()
    
    
  •  ほら、できたないな。Pascal 変換はうまくいっていますけど、Camel 変換がうまくいっていないですね。

  •  タイトル変えなきゃ。「getdata と入力したら、GetData、または、getData と変換したかった」って。 っていうか、getdata はタイトル以降出てきてないですねorz。



  •  (後日)調べました。ToCamelメソッドに以下を追記すれば OK でした。
  • ' 先頭1文字を小文字に変換
    Dim firstHalf As String = target.Chars(0).ToString().ToLower()
    Dim secondHalf As String = target.Substring(1)
    target = firstHalf & secondHalf
    
    ' aaa.BbbCcc になっているので、カンマの後の B を b に変換
    Dim index = target.IndexOf(".")
    While index <> -1
        Dim item1 = target.Substring(0, index) ' 開始からカンマまで
        Dim item2 = target.Substring(index + 1, 1)   ' カンマの後、次の先頭1文字
        Dim item3 = target.Substring(index + 1 + 1) ' カンマと次の先頭1文字の後ろ以降
    
        item2 = item2.ToLower()
        target = item1 & "." & item2 & item3
        index = target.IndexOf(".", index + 1)
    End While
    
  •  最後までこの記事を読んでいただき、ありがとうございました。

  • スポンサーリンク