OSDN Git Service

81b5597c290a74749c23e55c967440134ec1a593
[wptscs/wpts.git] / HmLib / Utilities / StringUtils.cs
1 // ================================================================================================
2 // <summary>
3 //      文字列処理に関するユーティリティクラスソース。</summary>
4 //
5 // <copyright file="StringUtils.cs" company="honeplusのメモ帳">
6 //      Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
7 // <author>
8 //      Honeplus</author>
9 // ================================================================================================
10
11 namespace Honememo.Utilities
12 {
13     using System;
14     using System.Text.RegularExpressions;
15
16     /// <summary>
17     /// 文字列処理に関するユーティリティクラスです。
18     /// </summary>
19     /// <remarks>一部メソッドは、Apache Commons LangのStringUtilsやJava標準のStringを参考にしています。</remarks>
20     public static class StringUtils
21     {
22         #region 定数
23
24         /// <summary>
25         /// <see cref="FormatDollarVariable"/>で使用する正規表現。
26         /// </summary>
27         private static readonly Regex DollarVariableRegex = new Regex("\\$([0-9]+)");
28
29         #endregion
30
31         #region 初期化メソッド
32
33         /// <summary>
34         /// 渡された文字列をチェックし、<c>null</c>だった場合には空の文字列を返します。
35         /// それ以外の場合には渡された文字列を返します。
36         /// </summary>
37         /// <param name="str">チェックを行う対象となる文字列。</param>
38         /// <returns>渡された文字列、<c>null</c>の場合には空の文字列。</returns>
39         public static string DefaultString(string str)
40         {
41             return StringUtils.DefaultString(str, String.Empty);
42         }
43
44         /// <summary>
45         /// 渡された文字列をチェックし、<c>null</c>だった場合には指定されたデフォルトの文字列を返します。
46         /// それ以外の場合には渡された文字列を返します。
47         /// </summary>
48         /// <param name="str">チェックを行う対象となる文字列。</param>
49         /// <param name="defaultString">渡された文字列が<c>null</c>の場合に返されるデフォルトの文字列。</param>
50         /// <returns>渡された文字列、<c>null</c>の場合にはデフォルトの文字列。</returns>
51         public static string DefaultString(string str, string defaultString)
52         {
53             if (str == null)
54             {
55                 return defaultString;
56             }
57
58             return str;
59         }
60
61         #endregion
62
63         #region 切り出しメソッド
64
65         /// <summary>
66         /// 指定された文字列の部分文字列を例外を発生させることなく取得します。
67         /// </summary>
68         /// <param name="str">部分文字列の取得対象となる文字列。</param>
69         /// <param name="startIndex">部分文字列の開始位置。</param>
70         /// <returns>開始位置からの部分文字列。</returns>
71         public static string Substring(string str, int startIndex)
72         {
73             return StringUtils.Substring(str, startIndex, Int32.MaxValue);
74         }
75
76         /// <summary>
77         /// 指定された文字列の部分文字列を例外を発生させることなく取得します。
78         /// </summary>
79         /// <param name="str">部分文字列の取得対象となる文字列。</param>
80         /// <param name="startIndex">部分文字列の開始位置。</param>
81         /// <param name="length">部分文字列の文字数。</param>
82         /// <returns>開始位置から指定された文字数の部分文字列。文字数が足りない場合、最後まで。</returns>
83         public static string Substring(string str, int startIndex, int length)
84         {
85             if (str == null)
86             {
87                 return null;
88             }
89
90             int i = startIndex > 0 ? startIndex : 0;
91             if (i > str.Length)
92             {
93                 return String.Empty;
94             }
95
96             int l = length > 0 ? length : 0;
97             if (l > str.Length - i)
98             {
99                 l = str.Length - i;
100             }
101
102             return str.Substring(i, l);
103         }
104
105         #endregion
106
107         #region 文字列チェック
108
109         /// <summary>
110         /// この文字列の指定されたインデックス以降の部分文字列が、指定された接頭辞で始まるかどうかを判定します。
111         /// </summary>
112         /// <param name="str">チェックを行う対象となる文字列。</param>
113         /// <param name="prefix">接頭辞。</param>
114         /// <param name="toffset">この文字列の比較を開始する位置。</param>
115         /// <returns>始まる場合<c>true</c>。<paramref name="toffset"/>が負の値の場合、<paramref name="str"/>の長さより大きい場合<c>false</c>。それ以外で<paramref name="prefix"/>が空の場合は<c>true</c>。</returns>
116         /// <remarks>引数の<c>null</c>は許容、<paramref name="str"/>のみまたは<paramref name="prefix"/>のみ<c>null</c>は<c>false</c>、<paramref name="prefix"/>も<c>null</c>は<c>true</c>を返す。</remarks>
117         public static bool StartsWith(string str, string prefix, int toffset)
118         {
119             // nullチェック
120             if (str == null)
121             {
122                 return prefix == null;
123             }
124             else if (prefix == null)
125             {
126                 return false;
127             }
128
129             // 範囲チェック
130             if (toffset < 0 || toffset >= str.Length)
131             {
132                 return false;
133             }
134
135             // 長さチェック
136             if (prefix.Length == 0)
137             {
138                 return true;
139             }
140
141             // substringしてしまうと遅いので、先頭1文字だけは自前でチェック
142             if (str[toffset] != prefix[0])
143             {
144                 return false;
145             }
146
147             // 後は普通のStartWithで処理
148             return str.Substring(toffset).StartsWith(prefix);
149         }
150
151         #endregion
152
153         #region 書式化メソッド
154
155         /// <summary>
156         /// 指定した文字列の書式項目を、指定した配列内の対応するオブジェクトの文字列形式に置換します。
157         /// </summary>
158         /// <param name="format">$1~$数値の形式でパラメータを指定する書式指定文字列。</param>
159         /// <param name="args">書式設定対象オブジェクト。</param>
160         /// <returns>書式項目が<paramref name="args"/>の対応するオブジェクトの文字列形式に置換された<paramref name="format"/>のコピー。</returns>
161         /// <exception cref="ArgumentNullException"><paramref name="format"/>または<paramref name="args"/>が<c>null</c>の場合。</exception>
162         /// <remarks>.netではなくPerl等で見かける$~形式のフォーマットを行う。</remarks>
163         public static string FormatDollarVariable(string format, params object[] args)
164         {
165             // nullチェック
166             Validate.NotNull(format, "format");
167             Validate.NotNull(args, "args");
168
169             // 正規表現で$1~$数値のパラメータ部分を抜き出し、対応するパラメータに置き換える
170             // 対応するパラメータが存在しない場合、空文字列となる
171             return DollarVariableRegex.Replace(
172                 format,
173                 (Match match)
174                 =>
175                 {
176                     int index = Int32.Parse(match.Groups[1].Value) - 1;
177                     return args.Length > index ? ObjectUtils.ToString(args[index]) : String.Empty;
178                 });
179         }
180
181         #endregion
182
183         #region 比較メソッド
184
185         /// <summary>
186         /// 指定した2つのStringオブジェクトを比較し、並べ替え順序におけるそれらの相対位置を示す整数を返します。
187         /// </summary>
188         /// <param name="strA">比較対象の第1文字列。</param>
189         /// <param name="strB">比較対象の第2文字列。</param>
190         /// <returns>
191         /// 0未満: <paramref name="strA"/>が<paramref name="strB"/>より小さい,
192         /// 0: <paramref name="strA"/>と<paramref name="strB"/>は等しい,
193         /// 0より大きい: <paramref name="strA"/>が<paramref name="strB"/>より大きい。
194         /// </returns>
195         /// <remarks>
196         /// パラメータには<c>null</c>が指定可能です。<c>null</c>または空文字列は最も大きい値とみなします。
197         /// <c>null</c>と空文字列を比較した場合、<c>null</c>を大きい値とみなします。
198         /// </remarks>
199         public static int CompareNullsLast(string strA, string strB)
200         {
201             // まずnullの判定
202             if (strA == null && strB == null)
203             {
204                 return 0;
205             }
206             else if (strA == null)
207             {
208                 return 1;
209             }
210             else if (strB == null)
211             {
212                 return -1;
213             }
214
215             // 次に空文字列の判定(nullと空文字列は一応区別)
216             if (String.IsNullOrEmpty(strA) && String.IsNullOrEmpty(strB))
217             {
218                 return 0;
219             }
220             else if (String.IsNullOrEmpty(strA))
221             {
222                 return 1;
223             }
224             else if (String.IsNullOrEmpty(strB))
225             {
226                 return -1;
227             }
228
229             // どちらもnull or 空で無い場合は普通に判定
230             return String.Compare(strA, strB);
231         }
232
233         #endregion
234     }
235 }