各言語ごとの文字列

| |C#|JavaScript|Perl|Python|
|---|---|---|---|---|
|リテラル|[``"文字列"``](#c)|[``"文字列"`` or ``'文字列'`` or `` `x=${x + 1}` ``](#javascript)|[``"文字列"`` or ``'文字列'``](#perl)|[``"文字列"`` or ``'文字列' ``](#python)|
|結合|[「+」演算子](#c-javascript-python)|[「+」演算子](#c-javascript-python)|[「.」演算子](#perl-1)|[「+」演算子](#c-javascript-python)|
|大規模な結合|[StringBuilder を使用](#c-1)|[+= で結合](#javascript-1)|[文字列に .= で結合](#perl-2)|[``"".join(iterator)`` を使用](#python-1)|
|比較|[==, !=, >, >=, <, <=](#c-2)|[==, !=, >, >=, <, <=](#javascript-2)|[eq, ne, gt, ge, lt, le](#perl-3)|[==, !=, >, >=, <, <=](#python-2)|
|部分文字列を取得|[``text.Substring(startPos, endPos - startPos)``](#c-3)|[``text.substring(startPos, endPos)``](#javascript-3)|[``substr($text, $startPos, $endPos - $startPos)``](#perl-4)|[``text[startPos:endPos]``](#python-3)|
|検索|[``int pos = text.IndexOf("hoge")``](#c-4)|[``let pos = text.indexOf("hoge")``](#javascript-4)|[``$pos = index($text, "hoge")``](#perl-5)|[``pos = text.find("hoge")``](#python-4)|
|置換|[``var text = text.Replace("old", "new")``](#c-5)|[``text = text.replaceAll("old", "new")``](#javascript-5)|[``$text =~ s/old/new/g``](#perl-6)|[``text = text.replace("old", "new")``](#python-5)|
|文字単位の置換|[]()|[]()|[``$text =~ tr/a-z/A-Z/``](#perl-7)|[``text.translate(str.maketrans('abc','ABC'))``](#python-6)|
|リストの要素を結合 (join)|[``string.Join(",", items)``](#c-6)|[``items.join(",")``](#javascript-6)|[``join(",", @items)``](#perl-8)|[``",".join(items)``](#python-7)|
|デリミターで分割|[``var items = text.Split(',')``](#c-7)|[``items = text.split(",")``](#javascript-7)|[``@items = split(/,/, $text)``](#perl-9)|[``items = text.split(",")``](#python-8)|
|n文字目の文字コードを取得|[``char code = text[n]``](#c-8)|[``let code = text.codePointAt(n)``](#javascript-8)|[``$code = ord(substr($text, $n, 1))``](#perl-10)|[``code = ord(text[n])``](#python-9)|
|文字コードを文字列に|[``var text = ((char)code).ToString()``](#c-9)|[``let text = String.fromCodePoint(code)``](#javascript-9)|[``$text = chr($code)``](#perl-11)|[``text = chr(code)``](#python-10)|
|数値→文字列|[``x.ToString()``](#c-10)|[``x.toString()``](#javascript-10)|[``$x``](#perl-12)|[``str(x)``](#python-11)|
|文字列→数値|[``int.Parse(text)``](#c-11)|[``Number(text)``](#javascript-11)|[``$text``](#perl-13)|[``int(text)``](#python-12)|
|文字列からバイト列|[``Encoding.UTF8.GetBytes(text)``](#c-12)|[``new TextEncoder().encode(text)``](#javascript-12)|[``Encode::encode("utf8", $text)``](#perl-14)|[``text.encode("utf8")``](#python-13)|
|バイト列から文字列|[``Encoding.UTF8.GetString(buff)``](#c-13)|[``new TextDecoder().decode(buff)``](#javascript-13)|[``Encoding::decode("utf8", $buff)``](#perl-15)|[``buff.decode("utf8")``](#python-14)|
|現在の日時|[``DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")``](#c-14)|[``new Date().toLocaleString()``](#javascript-14)|[]()|[``datetime.now().strftime("%Y/%m/%d %H:%M:%S")``](#python-15)|


# 基本

## リテラル

### C#

``"文字列"``

以下のプレフィックス付きのものがある
- ``@"""\""でエスケープしない文字列"``
    「"」自身を表現したい場合は「""」
- ``$"式の埋め込み: {4 * 3}"``
    「{」「}」自身を表現したい場合は「{{」「}}」

### JavaScript

``"文字列"`` or ``'文字列'`` or `` `x=${x + 1}` ``

### Python

``"文字列"`` or ``'文字列' ``

「"」と「'」は、機能的な差はない。中で異なる「"」「'」がエスケープなしで使える。
以下のプレフィックス付きのものがある
- ``r'"\"でエスケープしない文字列'``
    - r'...' の中で「'」を使いたい場合、``r'\'abc'``とすれば使えるが結果は「'abc」ではなく「\\'abc」となる
    - 末尾を「\」にはできない
    - r"..." でも R"..." でも違いはないけど、VSCode では配色が変わる。
        どうやら、r"..." は正規表現、R"..." はその他といった感じっぽい
- ``f'式の埋め込み: {4 * 3}'``
    - f'...' の {} の中では「'」は使えない。エスケープも不可能
    - 「{」「}」自身を表現したい場合は「{{」「}}」

### Perl

``"文字列"`` or ``'文字列'``

- 「"」
    - 変数の埋め込みが可能
    - 「\n」で改行
    - 「\」「"」「$」「@」を含めたい場合は「\」でエスケープ
- 「'」
    - 変数埋め込み機能がない
    - 「\」は基本的にはエスケープ不要
    - 「\」は、直後に「\」「'」があるときのみ、エスケープ記号として働く
        - 「`C:\Temp`」は `'C:\Temp'`
        - 「`x='y'`」は`'x=\'y\''`
        - 「`\`」は `'\\'`
        - 「`\\zzz`」は `'\\\\zzz'`

## 結合

### C#, JavaScript, Python

「+」演算子

### Perl

「.」演算子

## 大規模な結合

### C#

StringBuilder を使用

```C#
// 1000000文字の 'a' を生成
var sbText = new StringBuilder();
for (int i = 0; i < 1000000; i++) { sbText.Append("a"); }
var text = sbText.ToString();
// 以下だと、すごく遅い（見てる間に終わらないレベル）
var text2 = "";
for (int i = 0; i < 1000000; i++) { text2 += "a"; }
```

### JavaScript

+= で結合

```JavaScript
let text = "";
for (let i = 0; i < 1000000; i++) { text += "a"; }
```
これで、すぐに終わる。
ちなみに、``text = text + "a";`` とか ``text = "a" + text;`` でもすぐ終わる。

### Python

``"".join(iterator)`` を使用

```Python
def generateText(n):
    for i in range(n):
        yield 'a'

text = "".join(generateText(1000000))
```

普通に += で結合していくのに比べて 10倍以上速い。
+= でも、C#ほどは遅くはないので、速度が重要でない場合は += でもいいと思う。

### Perl

文字列に .= で結合

```Perl
my $text = "";
foreach $i (1 .. 10000000) {
	$text .= "a";
}
```

``$text = $text . "a";`` でも変わらないっぽい。
（昔試したときは、遅かったような気がする...）

## 比較

### C#

==, !=, >, >=, <, <=

### JavaScript

==, !=, >, >=, <, <=

### Python

==, !=, >, >=, <, <=

### Perl

eq, ne, gt, ge, lt, le

Perl では、文字列専用の比較演算子がある。
比較に限らず、ほぼすべてのオペレーションで、文字列と数値で異なる表現になっている。
このおかげで、Perlでは、文字列と数値の違いを意識する必要がなくなっている。

Perl では、1 + 1 は、つねに 2 である。
"1" + 1、"1" + "1" 、1 + "1" 、これら、すべて 2 となる。

## 部分文字列を取得

### C#

``text.Substring(startPos, endPos - startPos)``

``text.Substring(startPos)`` で startPos 文字目以降

### JavaScript

``text.substring(startPos, endPos)``

``text.substr(startPos, endPos - startPos)`` もある。
``text.substr(startPos)`` で startPos 文字目以降

### Python

``text[startPos:endPos]``

``text[startPos:]`` で startPos 文字目以降
``text[i]`` は、i 文字目の文字（1文字だけの文字列）

### Perl

``substr($text, $startPos, $endPos - $startPos)``

## 検索

### C#

``int pos = text.IndexOf("hoge")``

見つからない場合は -1 が返される。
後ろから検索する場合は、``pos = text.LastIndexOf("hoge")``

### JavaScript

``let pos = text.indexOf("hoge")``

見つからない場合は -1 が返される。
後ろから検索する場合は、``pos = text.lastIndexOf("hoge")``

### Python

``pos = text.find("hoge")``

見つからない場合は -1 が返される。
後ろから検索する場合は、``pos = text.rfind("hoge")``

同等の機能で index, rindex もあるが、これらは見つからなかった場合、例外が発生する。

### Perl

``$pos = index($text, "hoge")``

見つからない場合は -1 が返される。
後ろから検索する場合は、``$pos = rindex($text, "hoge")``

## 置換

### C#

``var text = text.Replace("old", "new")``

### JavaScript

``text = text.replaceAll("old", "new")``

replace メソッドもあるが、こちらは、最初の1つしか置換されない。

replace, replaceAll は、変換元に正規表現を指定可能。
``text = text.replace(/[0-9]+/g, "#")``
/.../g の「g」がなければ、最初の１つだけが置換される。
（replaceAll は「g」がついてないとエラーになる）

### Python

``text = text.replace("old", "new")``

### Perl

``$text =~ s/old/new/g``

「old」の部分は正規表現。

## 文字単位の置換

### Python

``text.translate(str.maketrans('abc','ABC'))``

これで、"a,b,c,d,e,f,g" → "A,B,C,d,e,f" のように変換される。

translate は、文字コード→文字コードor文字列 の変換テーブルを dict で渡す(と、ドキュメントには書いてある)。
が、テーブルは dict型 じゃなくても大丈夫っぽい。

```Python
class ToUpperTrans:
    def __getitem__(self, code):
        if code >= 97 and code <= 122: # code が 'a'～'z'なら...
            return code - 97 + 65 # 'A'～ に変換して返す
        else:
            return code

text = "hoge123"
print(text.translate(ToUpperTrans()))
# 「HOGE123」 が表示される
```

### Perl

``$text =~ tr/a-z/A-Z/``

これで、小文字から大文字に変換される。

## リストの要素を結合 (join)

### C#

``string.Join(",", items)``

### JavaScript

``items.join(",")``

items は、配列のみ。

### Python

``",".join(items)``

items の要素は文字列でないとダメ（ちょい面倒）
要素が文字列以外の場合は、以下のように文字列に変換する。

```Python
items = [1,2,3,4]
print(",".join(map(str, items)))
```

### Perl

``join(",", @items)``

## デリミターで分割

### C#

``var items = text.Split(',')``

2文字以上のデリミターで区切りたい場合は、
``items = text.Split(new string[] {"::"}, StringSplitOptions.None)``

なんだか、煩雑な感じなので、以下の方が簡単かも...
``items = Regex.Split(text, "::")``

### JavaScript

``items = text.split(",")``

デリミタの指定は正規表現でもOK。

```javascript
const text = "a:b::c:d";
const items1 = text.split(":");
console.log(items1); // → ['a', 'b', '', 'c', 'd']
const items2 = text.split(/:+/);
console.log(items2); // → ['a', 'b', 'c', 'd']
```

### Python

``items = text.split(",")``

### Perl

``@items = split(/,/, $text)``

デリミタの指定は必ず正規表現。

```Perl
my @items = split(":+", "a:b::c:d");
print join(",", @items); # → 「a,b,c,d」と出力される
```

## n文字目の文字コードを取得

### C#

``char code = text[n]``

※ code は UTF16 の 16bit コード

### JavaScript

``let code = text.codePointAt(n)``

### Python

``code = ord(text[n])``

### Perl

``$code = ord(substr($text, $n, 1))``

## 文字コードを文字列に

### C#

``var text = ((char)code).ToString()``

※ code は、UTF16 の 16bit code

unicode のコードから文字を得たい場合は、

```C#
int code = 0x1F4A9;
string unko = Encoding.UTF32.GetString(BitConverter.GetBytes(code));
```

### JavaScript

``let text = String.fromCodePoint(code)``

### Python

``text = chr(code)``

### Perl

``$text = chr($code)``

# 変換

## 数値→文字列

### C#

``x.ToString()``

### JavaScript

``x.toString()``

### Python

``str(x)``

### Perl

``$x``

※ Perl の場合、特に変換する必要はない

## 文字列→数値

### C#

``int.Parse(text)``

int以外は、``float(text)``, ``double(text)`` とか...

### JavaScript

``Number(text)``

### Python

``int(text)``

浮動小数点の場合は ``float(text)``

### Perl

``$text``

Perl の場合、特に変換する必要はないが、bit 演算する場合は、``int($text)`` 等で変換が必要。

## 文字列からバイト列

### C#

``Encoding.UTF8.GetBytes(text)``

shift-jis の場合は、``Encoding.GetEncoding("shift_jis").GetBytes(text)``

### JavaScript

``new TextEncoder().encode(text)``

utf8 以外は、なんらかの外部ライブラリを使う必要があるっぽい。

### Python

``text.encode("utf8")``

### Perl

``Encode::encode("utf8", $text)``

※ 要 ``use Encode;``

## バイト列から文字列

### C#

``Encoding.UTF8.GetString(buff)``

shift-jis の場合は、``Encoding.GetEncoding("shift_jis").GetString(buff)``

### JavaScript

``new TextDecoder().decode(buff)``

utf8 以外は、なんらかの外部ライブラリを使う必要があるっぽい。

### Python

``buff.decode("utf8")``

### Perl

``Encoding::decode("utf8", $buff)``

# その他

## 現在の日時

### C#

``DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")``

### JavaScript

``new Date().toLocaleString()``

### Python

``datetime.now().strftime("%Y/%m/%d %H:%M:%S")``

f"...." を使用する場合は、
`f"{datetime.now():%Y/%m/%d %H:%M:%S}"`

「秒」より細かい時間も欲しい場合は、
`f"{datetime.now():%Y/%m/%d %H:%M:%S.%f}"`