Skip to content

Instantly share code, notes, and snippets.

@iwashihead
Created November 7, 2017 08:19
Show Gist options
  • Save iwashihead/1600c478a1fb189756e7dfc0802d86f3 to your computer and use it in GitHub Desktop.
Save iwashihead/1600c478a1fb189756e7dfc0802d86f3 to your computer and use it in GitHub Desktop.
RubyのhashをC#のHashtableに変換するパーサ
using System;
using System.Collections;
using UnityEngine;
/// <summary>
/// =======================================================
/// RubyのhashをC#のHashTableに変換
/// =======================================================
///
/// 文字列キーとシンボルをキーとする記述方法がありますが
/// 一旦文字列キーのパースのみサポート.
/// シンボルをキーとする場合のパースは追って対応予定.
///
/// "value"=> 100 ...対応
/// :value => 100 ...非対応
/// value: => 100 ...非対応
/// =======================================================
/// </summary>
public class RubyHashParser
{
const char ST_CHAR = '{';
const char ED_CHAR = '}';
static readonly char[] SPLIT_CHARS = new char[]{ ',' };
static readonly string[] KPV_SPLIT = new string[]{ "=>" };
public class ParseFailedException : Exception {
public ParseFailedException(string message) : base(message) { }
}
/// <summary>
/// Rubyのhash形式の文字列をC#のHashtableに変換します.
/// </summary>
public static Hashtable Parse(string hashString)
{
if (string.IsNullOrEmpty (hashString)) {
return null;
}
var stIdx = hashString.IndexOf(ST_CHAR);
var edIdx = hashString.LastIndexOf (ED_CHAR);
if (stIdx == -1 || edIdx == -1) {
throw new ParseFailedException ("Invalid Format");
}
var hashTable = new Hashtable ();
// {}で囲まれた中身(content)を取得
var content = hashString.Substring (stIdx + 1, edIdx - stIdx - 1);
// ,で分割してキーバリューペアリストを取得
var contentArray = content.Split ( SPLIT_CHARS );
if (contentArray == null || contentArray.Length <= 0) {
return hashTable;//empty content.
}
for (int i = 0; i < contentArray.Length; i++) {
if (string.IsNullOrEmpty (contentArray [i]) || contentArray [i].Length < 4) {
continue;
}
var kpv = contentArray [i].Split ( KPV_SPLIT, StringSplitOptions.None );
if (kpv == null || kpv.Length < 2) {
continue;
}
var key = kpv [0].Trim();
var value = kpv [1].TrimStart().TrimEnd();
key = StripDoubleQuate (key);
// キーチェック.
if (string.IsNullOrEmpty (key)) {
continue;//nullキーは除外.
}
if (hashTable.ContainsKey (key)) {
continue;//キーの重複時の上書きは対応しない.
}
value = StripDoubleQuate (value);
hashTable.Add (key, value);
}
return hashTable;
}
/// <summary>
/// ダブルクォーテーションで囲まれた文字列から
/// ダブルクォーテーションを外した文字列を返す.
/// </summary>
private static string StripDoubleQuate(string value)
{
if (string.IsNullOrEmpty (value) || value.Length < 2) {
return value;
}
if (value [0] == '\"' && value [value.Length - 1] == '\"') {
return value.Substring (1, value.Length - 2);
}
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment