【C#】制御文字を文字列から削除する

2023年2月7日

iPhoneなどのスマホで撮った画像や動画の撮影日時などには、日付文字列中に制御文字が含まれているため

//日時のプロパティは日付設定
DateTime dt;

//DateTimeに変換
if (DateTime.TryParse(shoot_date, out dt))
{
    return dt.ToString("yyyyMMddHHmmss");
}

とやってもDateTime.TryParse関数で日付とみなされずfalseで帰ってきます。
なので関係ない文字列を除去する考えました。

文字列から数値と"/"と":"とスペースだけを取得する

欲しい文字以外は捨ててしまいます。ロジックは以下の通りです。
今回はこのロジックで対応しました。

StringBuilder sbDate = new StringBuilder();
//日付変更に失敗した場合、0-9, /, : spaceだけ抜き出す。
foreach (char c in shoot_date.ToCharArray())
{
    if (Regex.IsMatch(c.ToString(), @"[0-9]|/|:|\s"))
    {
        sbDate.Append(c);
    }
}

if (DateTime.TryParse(sbDate.ToString(), out dt))
{
    return dt.ToString("yyyyMMddHHmmss");
}

正規表現で必要な文字(0-9、/、:、スペース)だけを抜き出しています。
replace関数で一気に置き換えてもいいですね。そうすれば1行で済みそうです。

iPhoneの画像の撮影日時には何の文字が入っているのか

最初は制御文字を除くLinQを使ったコードで不要な文字を取ってやればいいと思い、試してみましたがダメでした。

//制御文字を取り除く
shoot_date= new string(shoot_date.Where(c => !char.IsControl(c)).ToArray());

//DateTimeに変換
if (DateTime.TryParse(shoot_date, out dt))
{
    //trueにならないのでここに入ってこない
    return dt.ToString("yyyyMMddHHmmss");
}

というわけで調べてみました。

この画像はiPhone 5sで「2018/07/19 13:35」に取れたものです。

これを分解してみました。

文字2018/?07/?19??13:35
ASCII8206504849565782064855478206495732820782064951585153

この8206と8207を調べてみました。結果、

8206は左から文字を書き始める制御文字
8207は右から文字を書き始める制御文字

と出てきました。自信ががないので違う場合はご指摘頂ければと思います。
なんでこんなものが入っているかよくわかりませんがtryParse関数の邪魔をしています。

isContol関数で制御文字と判断されないのはASCIIコード(0~255)ではないからなのかなと思います。

ここまで読んで頂いてありがとうございます。

C#C#

Posted by nomux2