はじめに
@ki_87 さんの[C#]バイト数と文字数の比較で、漢字とひらがなの入力を制限する 英数字のみを読んで、以前に私が担当していたシステムでも、前任者の方が同様の方法で入力文字列のチェックをしていたことを思い出しました。
入力文字列のチェックについては実装方法は1つではないと思うので、幾つかの方法を検討して実装してみました。
仕様
- 入力文字列が「半角英数字のみ」で構成されているかをチェックします。
- 「半角英数字のみ」であればtrue、そうでなければfalseを返します。
- 英字については、大文字と小文字のどちらでも使えるものとします。
- 「半角英数字のみ」なので、全角文字は許可しません。
実装方法
文字数とバイト数を比較する方法
- @ki_87 さんの方法は「文字列の文字数とバイト数を比較する」というもので、記事ではShift_JISと書かれていたのでそのままの仕様で実装してみました。
- コメントが無いと、何のためにバイト数と文字数を比較しているのかが分からなくなりそうな感じを受けます。
- 例えば「_」のような半角記号も1バイトなので、文字数とバイト数を比較するだけでは半角記号を除去できないという欠点が内在しています。
TextChecker.cs
using System.Text;
namespace CSharpStudy.Text
{
public class TextChecker
{
/// <summary>
/// 引数の文字列が半角英数字のみで構成されているかを調べる。
/// </summary>
/// <param name="text">チェック対象の文字列。</param>
/// <returns>引数が英数字のみで構成されていればtrue、そうでなければfalseを返す。</returns>
public static bool IsOnlyAlphanumeric1(string text)
{
var enc = Encoding.GetEncoding("Shift_JIS");
// 「Shift_JISのバイト数=文字数」なら英数字のみとみなす。
return (enc.GetByteCount(text) == text.Length);
}
}
}
正規表現を使った方法(1)
- 正規表現さえ読み解ければ、コメントが無くても半角英数字とマッチするかを判定していることが分かります。
- コードも簡潔で半角記号の問題にも対応しているので、私ならこの実装方法を採用すると思います。
TextChecker.cs
using System.Text.RegularExpressions;
namespace CSharpStudy.Text
{
public class TextChecker
{
/// <summary>
/// 引数の文字列が半角英数字のみで構成されているかを調べる。
/// </summary>
/// <param name="text">チェック対象の文字列。</param>
/// <returns>引数が英数字のみで構成されていればtrue、そうでなければfalseを返す。</returns>
public static bool IsOnlyAlphanumeric2(string text)
{
// 文字列の先頭から末尾までが、英数字のみとマッチするかを調べる。
return (Regex.IsMatch(text, @"^[0-9a-zA-Z]+$"));
}
}
}
正規表現を使った方法(2)
- 数字を表す正規表現として、
[0-9]
の代わりに\d
を使っています。- 単純に
\d
を使うと全角の数字もマッチしてしまうため、Regex.IsMatch()
の第3引数としてRegexOptions.ECMAScriptを指定しています。
- 単純に
- 動作は「正規表現を使った方法(1)」と同じですが、コードが分かりにくくなるのでこの実装は避けた方が良さそうです...
TextChecker.cs
using System.Text.RegularExpressions;
namespace CSharpStudy.Text
{
public class TextChecker
{
/// <summary>
/// 引数の文字列が半角英数字のみで構成されているかを調べる。
/// </summary>
/// <param name="text">チェック対象の文字列。</param>
/// <returns>引数が英数字のみで構成されていればtrue、そうでなければfalseを返す。</returns>
public static bool IsOnlyAlphanumeric3(string text)
{
// 文字列の先頭から末尾までが、英数字のみとマッチするかを調べる。
return (Regex.IsMatch(text, @"^[\da-zA-Z]+$", RegexOptions.ECMAScript));
}
}
}