Created
November 7, 2017 08:19
-
-
Save iwashihead/1600c478a1fb189756e7dfc0802d86f3 to your computer and use it in GitHub Desktop.
RubyのhashをC#のHashtableに変換するパーサ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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