string str = "ABC1234あいうえお5678"; // 3 文字目の後から 9 文字の文字列を取得する string str1 = str.Substring(3, 9); // 4 文字目の後から末尾までの文字列を取得する string str2 = str.Substring(4);
String.IndexOfメソッドは、文字列内に指定した文字列と一致する部分があるかを探し、 見つかったら、最初に見つかった位置を 0 以上の整数で返す(先頭文字の位置が 0)。 見つからなければ、-1 を返す[2]。
string s1 = "あいうえおあいうえお"; Console.WriteLine(s1.IndexOf("うえ")); // 結果は "2" Console.WriteLine(s1.IndexOf("ウエ")); // 結果は "-1" Console.WriteLine(s1.IndexOf("")); // 結果は "0" Console.WriteLine(s1.IndexOf("うえ",5)); // 5文字目から探索,結果は "7"
位置は必要なく、文字列内に指定した文字列が存在するかどうかだけを知るには Containsメソッドを使用する。
string s1 = "あいうえおあいうえお"; Console.WriteLine(s1.Contains("うえ")); // 結果は true Console.WriteLine(s1.Contains("ウエ")); // 結果は false
Javaでは String str = "abc123"; の文字 'c' は str.charAt(2) として読みだすが、 c# では string str = "abc123"; の文字 'c' は str[2] として読みだせる。 見かけは配列のアクセスに似ているが、インデクサ[3]と呼ばれるものであり、全ての操作が配列と同じというわけではない。 この場合 str[2] は読み取り専用であり、str[2] = 'C'; のようにして、この文字を書き換えることはできない。 分かりやすく言えば、".charAt(2)" の表記を "[2]" に変えただけのものと解釈できる。C++でオペレータ[]をオーバーライドする場合と類似の機能である。
文字列の連結は Java と同様で、 C# で文字列連結するとき、string 型を += で連結するとパフォーマンスが落ちるので、ある程度の回数以上の文字列連結には StringBuilder を使う。 string は不変なので、+= での連結の度に新しいオブジェクトの生成と破棄がおこなわれる。
改行を付けるには stringBuffer.AppendLine("abc"); が便利である。AppendFormatもある。
Regex.Split[4]が単純な字句解析に役立つ。
using System; using System.Text.RegularExpressions; class Program { static void Main() { string operation = "3 * 5 = 15"; string[] operands = Regex.Split(operation, @"\s+"); // 空白文字で分割 foreach (string operand in operands) { Console.WriteLine(operand); } } }
3 * 5 = 15
using System; using System.Text.RegularExpressions; class Program { static void Main() { string sentence = "10 cats, 20 dogs, 40 fish and 1 programmer."; string[] digits = Regex.Split(sentence, @"\D+"); // 非数字(0,1, ... ,9)で分割 foreach (string value in digits) { Console.WriteLine(value); } } }
10 20 40 1
コンパイラの字句解析にはちょっと無理そう。 コンパイラの字句解析では、空白だけでなく、字種の変わり目でも分割しなければならない。 例えば int n+=_k+1 は、int, n, +=, _k, +, 1 に分割する。 C言語をルーツとするプログラミング言語では「_」(アンダーバー)は英字と同様の扱いとなることが多い。 字句規則に従った分割となるため、字句解析は一般に、数行のプログラムでは済まない。
"-170(-0.87%)" のような記述から、"-170" と "-0.87" を抽出したい。 C言語では strtok(s, "(") で、"-170" 、次いで strtok(NULL, "%") で "-0.87" が取り出せる。
C# では、符号 +, - 、小数点 . および数字以外で分割すればよいので、 Splitメソッドの第二引数を @"[^\+-\.\d]+" とすればよい。
末尾の文字列と一致するか調べるには EndsWithメソッドを使う。
string url = "http://home.a00.itscom.net/hatada/index.html"; // 末尾の文字列と一致するかどうかを判断する if (url.EndsWith(".html")) { MessageBox.Show("HTMLファイルです"); }
先頭の文字列と一致するか調べるには StartsWithメソッドを使う。
文字 ch が10進数の数字かどうか調べるには char.IsDigit(ch) を使う。 string型文字列 s の n 番目(先頭が0)の文字が数字かどうか調べるには char.IsDigit(s,n) を使う。 全角文字0、1、2、... 、9 も10進数とみなされるが、 漢字数字一、二、三、... やローマ数字T、U、V、... は10進数とみなさない。
文字列がASCIIの数値かどうかは次のようにして調べられる。
bool IsNumber(string str) { foreach (char c in str) { if (c < '0' || '9' < c) return false; } return true; }
ā, ī, ū, ē, ō は UNICODE では 0x101, 0x12B, 0x16B, 0x113, 0x14D である。
C#の 文字列 name が英数字記号または ā, ī, ū, ē, ō のみで構成されるかどうかを調べるプログラムを下に示す。
bool IsAscii(string name) { return new Regex("^[\x20-\x7E\u0101\u012B\u016B\u0113\u014D]+$").IsMatch(name); } // ASCIIコードおよび長音aiueo(2バイトコード)
文字列 strA と strB が等しいかどうか調べるには strA == strB を使う。 辞書順の並びを調べるには String.Compare(strA, strB) を使う。この値が負の時は strA の方が辞書順では先(小さい)、 ゼロのときは二つの文字列が等しい、正のときは辞書順では strA の方が後(大きい)。
文字列 s 中のある文字列 src を別の文字列 dst に置き換えるには String.Replaceメソッドを sReplaced = s.Replace(src, dst) のように使う。また、文字 cSrc を文字 cDst に置き換えるには sReplaced = s.Replace(cSrc, cDst) とする。
文字列の配列を区切り文字列で連結した文字列に変換するには、String.Join メソッドを使用する。 Join メソッドの第1引数には、区切り文字列、第2引数には、文字列配列を指定する。 第3、第4引数を指定して、配列要素の一部を連結することもできる。