# 文字列

Perl は正規表現を使った文字列操作に強く、同じ処理でも複数の書き方が可能な自由度の高い言語です。そのため、ファイルに保存された配列やタンパク質データを処理するのが容易で、かつてはバイオインフォマティクス分野で広く利用されていました。

過去形で語られるあたりに、歴史を感じてください。


## 文字列検索

文字列検索には `index` と `rindex` があり、前者は先頭から、後者は末尾から検索します。1 番目の引数に検索対象、2 番目の引数に検索したい文字列を指定します。検索がヒットすると開始位置のインデックスが返り、ヒットしなければ -1 が返されます。インデックスは 0 から始まります。

```perl
my $dna = "CATTGTACGTCGCGTAGCCATGTACGTCGCAGT";

my $pos1 = index($dna, "TAC");
print $pos1;
## 5

print substr($dna, $pos1, 3);
## TAC

my $pos2 = rindex($dna, "TAC");

print $pos2;
## 22

print substr($dna, $pos2, 3);
## TAC

print index($dna, "XXX");
## -1
```

正規表現によるパターンマッチングも可能で、`=~` 演算子を使って検索対象の文字列に正規表現を適用します。マッチ部分は後方参照で `$1`、`$2` などとして取得できます。


```perl
my $dna = "AGCGAGCCCAAGCTATGCTATTTAGCATTTCGATAAGTCGATGCTAAAAATA";

$dna =~ /(.*)(GCCC.+TAAA)(.*)/;

print $1;
## AGCGA

print $2;
## GCCCAAGCTATGCTATTTAGCATTTCGATAAGTCGATGCTAAA

print $3;
## AATA

print "start position: " . (length($1) - 1);
## start position: 4

print "end position:   " . (length($3) + length($2) + length($1) - 1);
## end position:   47
```

定義もしていない `$1` や `$2` が、気づいたら使えてます。理解しようとしてはいけません。任期が切れます。


## 文字列の結合

文字列を結合するにはピリオド `.` を用います。

```perl
my $dna_1 = "AGCTACGTAGTATT";
my $dna_2 = "ATGCTAGCAAATATATAAAA";

my $dna = $dna_1 . $dna_2;

print $dna;
## AGCTACGTAGTATTATGCTAGCAAATATATAAAA
```


## 文字列と配列の相互変換

文字列を指定した区切りで分割して配列に格納するには `split` を使用します。

```perl
my $csv = "NM200102.1,NM200110.2,NM200121.1,NM200123.2";

my @genes = split(/,/, $csv);

for (my $i = 0; $i < @genes; $i++) {
    print $genes[$i] . "\n";
}
## NM200102.1
## NM200110.2
## NM200121.1
## NM200123.2
```

配列を区切り文字で連結して文字列にするには `join` を使います。

```perl
my @data = (21, 31, 11, 12, 14, 11);
my $csv = join(",", @data);

print $csv . "\n";
## 21,31,11,12,14,11
```

## 文字列の切り出し

文字列の切り出しには `substr` を使用します。開始位置を負にすると末尾から数え、長さを省略すると末尾まで切り出されます。

```perl
my $dna = "AAACCCGGGTTT";

print substr($dna, 0, 3);
## AAA

print substr($dna, 3);
## CCCGGGTTT

print substr($dna, -3);
## TTT
```

正規表現でマッチした部分を切り出すことも可能です。

```perl
my $dna = "AAACCCGGGTTT";

$dna =~ /AAA(.+)GGG/;

print $1;
## CCC
```

## 文字列の置換

文字列の置換には `substr` または `s` 演算子を使います。`substr` では位置と長さを指定して置換できます。

```perl
my $dna = "AAACCCGGGTTT";

substr($dna, 3, 3, "XXX"); 

print $dna;
## AAAXXXGGGTTT
```

`s` 演算子を使うと正規表現で置換できます。

```perl
my $dna = "AGACXGTAXCGXTA";
$dna =~ s/X/C/;
print $dna;
## AGACCGTACCGXTA
```

すべての対象を置換するには `g` 修飾子を使います。

```perl
my $dna = "AGACXGTAXCGXTA";
$dna =~ s/X/C/g;
print $dna;
## AGACCGTACCGCTA
```

複雑なパターンの置換も可能です。

```perl
my $dna = "AAAAXAAACCCXCCCAAXAGGGTTTT";

$dna =~ s/AXA/CCC/g;
print $dna;
## AAACCCAACCCXCCCACCCGGGTTTT
```

```perl
my $dna = "AAGCAGTXCXGAGCAGXTXAGXTXA";

$dna =~ s/X(.)X/C$1C/g;
print $dna;
## AAGCAGTCCCGAGCAGCTCAGCTCA
```
