C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: 文字コードが混ざったテキストから文字コードのみ変換したい


(過去ログ 98 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■58663 / inTopicNo.1)  文字コードが混ざったテキストから文字コードのみ変換したい
  
□投稿者/ 腹痛中 (1回)-(2011/04/21(Thu) 11:27:19)

分類:[.NET 全般] 

いつもお世話になっています。

VB.NET 2010にて開発を行っています。

あるAccessのデータから抜き出したロングバイナリデータがあります。
そのバイナリデータをテキストにして保存したデータが以下になります。

'↓↓↓ サンプルデータ ここから ↓↓↓
500001355{\rtf1\ansi\ansicpg932\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern\fcharset128 \'82\'6c\'82\'72 \'83\'53\'83\'56\'83\'62\'83\'4e;}}
\deflang1041\horzdoc{\*\fchars !%),.:\'3b?]\}
\'a1\'a3\'a4\'a5\'a7\'a8\'a9\'aa\'ab\'ac\'ad\'ae\'af\'b0\'de\'df\'81\'41\'81\'42\'81\'43\'81\'44 …中略… \'81\'45\'81\'46\'81\'47\'81\'48\'81\'49}
{
\par \'95\'a0\'92\'c9\'82\'a0\'82\'e8\'97\'88\'89\'40
\par }
'↑↑↑ サンプルデータ ここまで ↑↑↑


この中には、Shift-Jisにてテキストデータが存在しています。
たとえば、「\'95\'a0」の95a0は「腹」の文字コードです。
が、「\'」が途中で混ざっていることによってChr関数などでは変換できませんでした。


「500001355{\rtf・・・」のデータはそのままで、文字変換できなかったデータ(\'95\'a0\'92\'c9・・・)のみ変換する事は可能なのでしょうか?

この変換できなかったデータには、半角全角混在の為、さらにややこしいと思いご質問させて頂きました。

皆様よろしくお願いいたします。
引用返信 編集キー/
■58664 / inTopicNo.2)  Re[1]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ みきぬ (960回)-(2011/04/21(Thu) 11:35:57)
残念ながらVBのサンプルコードはなかったけど、要するにこういうことだよね?

方法 : RTF をプレーンテキストに変換する (C# プログラミング ガイド)
http://msdn.microsoft.com/ja-jp/library/cc488002.aspx
引用返信 編集キー/
■58665 / inTopicNo.3)  Re[2]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ shu (639回)-(2011/04/21(Thu) 12:39:45)
2011/04/21(Thu) 13:25:27 編集(投稿者)
正規表現を使った方法です。

Imports System.Text.RegularExpressions
Imports System.Text

・・・・


        Dim reg As New Regex("((?<BEF>.*?)(\\'(?<DT>..)))", RegexOptions.Multiline)
        Dim enc As Encoding = Encoding.GetEncoding("Shift-JIS")

        Dim strSrc = "500001355{\rtf1\ansi\ansicpg932\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2" &
                   "\fmodern\fcharset128 \'82\'6c\'82\'72 \'83\'53\'83\'56\'83\'62\'83\'4e;}}" & Environment.NewLine &
                   "\deflang1041\horzdoc{\*\fchars !%),.:\'3b?]\}" &
                   "\'a1\'a3\'a4\'a5\'a7\'a8\'a9\'aa\'ab\'ac\'ad\'ae\'af\'b0\'de\'df\'81\'41\'81\'42\'81\'43\'81\'47\'81\'48\'81\'49}"
        Dim strDes = ""
        Dim lstBytes As New List(Of Byte)
        Dim intLastIdx As Integer = -1

        Dim m = reg.Match(strSrc)
        Do While m.Success
            Dim strBef = m.Groups("BEF").Value
            Dim strDT = m.Groups("DT").Value

            If strBef <> "" Then
                If lstBytes.Count > 0 Then
                    strDes &= enc.GetString(lstBytes.ToArray)
                End If
                lstBytes.Clear()
                strDes &= strBef
            End If

            If strDT <> "" Then
                lstBytes.Add(Convert.ToByte(strDT, 16))
            End If

            intLastIdx = m.Index + m.Length
            m = m.NextMatch
        Loop

        If lstBytes.Count > 0 Then
            strDes &= enc.GetString(lstBytes.ToArray)
        End If

        If intLastIdx >= 0 andalso intLastIdx < strSrc.Length Then
            strDes &= strSrc.Substring(intLastIdx)
        End If

引用返信 編集キー/
■58673 / inTopicNo.4)  Re[3]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ 腹痛中 (3回)-(2011/04/21(Thu) 17:54:13)
みきぬ様

簡単に言うとやりたい事はずばりそうなのですが、それで完結というわけじゃないので
ソースがあるとありがたかったです。
が、参考になりました!ありがとうございます。

shu様
ずばりこれでいけました!
正規表現を用いるのは頭の片隅にもありませんでした。
ありがとうございました。


解決済み
引用返信 編集キー/
■58709 / inTopicNo.5)  Re[4]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ 腹痛中 ※未解決 (1回)-(2011/04/23(Sat) 10:33:23)
皆様申し訳ございません。
解決済みのチェックを入れましたが、問題が発生いたしましたので再度お知恵をお貸しください。

shu様のソースでは、正常に変換する事が可能なのですが、処理速度的に問題がありました。
1件処理するのに、何十秒もかかることがあります。

変換不要な箇所を事前に削ってみたりしてみたのですが業務で使用するのにはかなり厳しいです。
正規表現部分の改造も試みているのですが、さらに良い知識があればお願いいたします。
引用返信 編集キー/
■58710 / inTopicNo.6)  Re[4]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ よねKEN (688回)-(2011/04/23(Sat) 16:29:18)
2011/04/23(Sat) 18:56:19 編集(投稿者)
2011/04/23(Sat) 16:32:22 編集(投稿者)

■No58673 (腹痛中 さん) に返信
> みきぬ様
> 
> 簡単に言うとやりたい事はずばりそうなのですが、それで完結というわけじゃないので
> ソースがあるとありがたかったです。

VBのソースがないだけで、C#のソースは提示のURLに載っていましたよ?
(文法は違いますが、RichTextBox.Rtfプロパティを使うという要点は十分に読み取れるかと思います)

■No58709 (腹痛中 ※未解決 さん) に返信
> shu様のソースでは、正常に変換する事が可能なのですが、処理速度的に問題がありました。

提示のソースコードが何をしているかは理解されていますか?
またその上で、期待通りの動作になっているか検証もしましょう。

処理速度の話はおいといて、
「「500001355{\rtf・・・」のデータはそのままで、文字変換できなかったデータ(\'95\'a0\'92\'c9・・・)のみ変換する事は可能なのでしょうか?」
という仕様からは、少しだけ期待しない結果になっていますので。

> 1件処理するのに、何十秒もかかることがあります。

提示のソースコードそのままかどうかわかりませんが、
ソースコードのどこがどれだけ処理がかかっているのか検証しましたか?
 
> 変換不要な箇所を事前に削ってみたりしてみたのですが業務で使用するのにはかなり厳しいです。

闇雲にいじるのではなく、何がボトルネックになっているのかをまず見極めなければ、
処理の最適化・高速化はできません。

質問文からは大量データを扱うなどの話はでてきていませんので、
shuさんのサンプルコードはそういった点は特に考慮されていないと思います。

「strDes &=」といように&演算子で文字列結合するのをやめてStringBuilderクラスを使えば
おそらく早くなるのではと思いますが、これは未検証です。

> 正規表現部分の改造も試みているのですが、さらに良い知識があればお願いいたします。

別案としてRegex.Replaceを使うという手があります。shuさん版より速いかどうかは未検証ですので、検証してくださいね。
詳しくはMSDNライブラリの以下を調べましょう。
http://msdn.microsoft.com/ja-jp/library/system.text.regularexpressions.regex.replace.aspx


' ※変数名とかメソッド名とか適当だから、くれぐれもこのコードそのままを実業務に適用しないように

Private encode As Encoding = Encoding.GetEncoding("Shift-JIS")
Private buf As Byte? ' Shift_JISの全角1バイト目を保管しておくバッファ。Nothingで初期化して使うこと

Private Function ConvertRtf(ByVal strSrc As String)
    buf = Nothing
    Return Regex.Replace(strSrc, "\\'(?<DT>..)", AddressOf Evaluator)
End Function

' Regex.ReplaceのMatchEvaluatorデリゲート用のメソッド
Private Function Evaluator(ByVal match As Match) As String
    Dim replacement As String
    Dim tmp As Byte = Convert.ToByte(match.Groups(1).Value, 16)
    If (buf Is Nothing) Then
        If (&H81 <= tmp And tmp <= &H9F) OrElse (&HE0 <= tmp And tmp <= &HFC) Then ' Shift_JISの全角1バイト目の判断
            buf = tmp
            replacement = String.Empty
        Else
            replacement = Encoding.Default.GetString(New Byte() {tmp})
        End If
    Else
        replacement = Encoding.Default.GetString(New Byte() {buf, tmp})
        buf = Nothing
    End If
    Return replacement
End Function

引用返信 編集キー/
■58711 / inTopicNo.7)  Re[5]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ Azulean (732回)-(2011/04/23(Sat) 18:21:22)
No58709 (腹痛中 ※未解決 さん) に返信
> 変換不要な箇所を事前に削ってみたりしてみたのですが業務で使用するのにはかなり厳しいです。

個人的には他人が書いたコード(サンプル)をそのまま業務で使うソフトウェアに組み入れるのはどうなのかなぁと感じます。
参考にするならまだしも…。
(著作権周りで問題にならんのかなぁと考える次第)
引用返信 編集キー/
■58739 / inTopicNo.8)  Re[5]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ shu (645回)-(2011/04/25(Mon) 11:05:01)
No58709 (腹痛中 ※未解決 さん) に返信
> 皆様申し訳ございません。
> 解決済みのチェックを入れましたが、問題が発生いたしましたので再度お知恵をお貸しください。
>
> shu様のソースでは、正常に変換する事が可能なのですが、処理速度的に問題がありました。
> 1件処理するのに、何十秒もかかることがあります。
>
> 変換不要な箇所を事前に削ってみたりしてみたのですが業務で使用するのにはかなり厳しいです。
> 正規表現部分の改造も試みているのですが、さらに良い知識があればお願いいたします。

正規表現を使った場合、長い文字列だと確かに時間がかかることはあるかもしれません。
よねKEN さんが書かれている案以外の部分だとnew RegExをしたときのオプションにCompiledを付加して
どうなるかですね。それでも遅いようでしたら、提案しといてなんですが正規表現ではなく文字列のIndexOfで
\'を検索し同様のことを実装されるとよいかと思います。
引用返信 編集キー/
■58741 / inTopicNo.9)  Re[6]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ みきぬ (961回)-(2011/04/25(Mon) 11:47:39)
どのくらいの長さの文字列を処理するのにどのくらいかかってるのか分からんので勘だけど、
元の文字列を適当に分割して個々に処理したら多少はましになったりしないのかしら。
引用返信 編集キー/
■58745 / inTopicNo.10)  Re[5]: 文字コードが混ざったテキストから文字コードのみ変換したい
□投稿者/ 風太郎 (2回)-(2011/04/25(Mon) 15:18:44)
2011/04/25(Mon) 15:19:52 編集(投稿者)
2011/04/25(Mon) 15:19:47 編集(投稿者)

腹痛中様

差し支えがなければ、後2、3のサンプル文字列を御提示頂けると助かります。

あくまでのお話ですが、何かしらの同一処理から吐き出された文字列の場合
同一のパターンを有している可能性が考えられます。

吐き出し元の処理に修正がある度に、受け手側の修正も必要になり
フレキシブルなアプリケーションにはならないかもしれませんが
パターンに基づく決め打ちの処理で高速化が図れるかもしれません。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -