Pythonで文字列を自由自在に扱う

## 環境
Python 3.6.5 :: Anaconda, Inc.

```python
$ python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 26 2018, 08:42:37) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
```
このようにインタープリタを起動する。
注意！コードに含まれる「>>>」や「...」はインタープリタの表示を再現しているものなので、SublimeText、VSCode、Pycharmなどのテキストエディタでコードを書く場合は省略可能。

## シングルコートとダブルコート
```python
>>> print('My name is Daisaku')
hello

>>> print("My name is Daisaku")
hello
```
シングルコートとダブブルコートは文字出力の際には区別されない。どちらを使うのかは完全に好み。


## 文字列としてシングルコートを出力したい
```
I don't know.
```
Pythonインタープリタを使って上記のような文字列を出力したいとする。

```python
>>> print('I don't know.')
  File "<stdin>", line 1
    print('I don't know.')
                 ^
SyntaxError: invalid syntax
```
文字列をシングルコートで囲っていると「どこからどこまでが文字列かわからんよ」と言われる。Qiitaのシンタックスハイライトも先程と比べて変な感じ。
ではどうするか。

```python
>>> print("I don't know.")
I don't know.
```
文字列全体をダブルコートで囲ってしまえば問題なく出力できる。
また、文字列全体をシングルコートで囲ったままでも上記と同じ出力は可能。

```python
>>> print('I don\'t know.')
I don't know.
```
「don't」のシングルコートに「 \ (バックスラッシュ)」を追加する。すると「このシングルコートは文字列だよ」とPythonに教えることが出来るため、「 I don't know. 」と出力される。

## 文字列としてダブルコートを出力したい
```
say "I don't know."
```
上記のように、ダブルコートを含んだ文字列を出力したいとする。

```python
>>> print('say "I don't know."')
  File "<stdin>", line 1
    print('say "I don't know."')
                      ^
SyntaxError: invalid syntax
```
シングルコートで囲っただけだとシンタックスエラーが生じる(そらそーだ)

```python
>>> print("say \"I don't know.\"")
say "I don't know."
```
文字列全体をダブルコートで囲み、文字列として表示させたいダブルコートには「 \ (バックスラッシュ)」を追加する。
「 \ (バックスラッシュ)」を追加しておけばどうにかできる。

但し、バックスラッシュを使わずに出力させることも可能。

```python
>>> print('''say "I don't know."''')
say "I don't know."
```

## 文字列を改行して表示させたい
```
hello.
How are you?
```
上記のように出力したいとする。

```python
print('hello.')
print('How are you?')
```
このように書くのは冗長的なので1文で書いてみる。

```python
>>> print('hello.\nHow are you?')
hello.
How are you?
```
改行したい箇所に「 \n 」を追加すれば狙った出力を得ることが出来る。
1点注意したいのは、Windowsのディレクトリ階層のような文字列を表示させたい場合。

```python
>>> print('C:\name\name')
C:
ame
ame
```
このように意図しない改行が行われてしまうため、下記のようにする。

```python
>>> print(r'C:\name\name')
C:\name\name
```

## 長文を複数行に渡って表示させたい
```
When history witnesses a great change,
Razgriz reveal itself, first as a dark demon.
As a demon, it uses its power to rain death upon a land and then it dies.
However after the period of the slumber, Razgriz returns.
```
このような長文を出力したいとする。
前述の「 \n 」を使うと非常に読みにくいコードになってしまうため、下記のように書く

```python
>>> print("""When history witnesses a great change,
... Razgriz reveal itself, first as a dark demon.
... As a demon, it uses its power to rain death upon a land and then it dies.
... However after the period of the slumber, Razgriz returns.""")
When history witnesses a great change,
Razgriz reveal itself, first as a dark demon.
As a demon, it uses its power to rain death upon a land and then it dies.
However after the period of the slumber, Razgriz returns.
```

このままだと少々コードが読みづらいので、3つのダブルコート直後にバックスラッシュを追加して下記のように書くとすっきりする。

```python
>>> print("""\
...When history witnesses a great change,
... Razgriz reveal itself, first as a dark demon.
... As a demon, it uses its power to rain death upon a land and then it dies.
... However after the period of the slumber, Razgriz returns.\
""")
When history witnesses a great change,
Razgriz reveal itself, first as a dark demon.
As a demon, it uses its power to rain death upon a land and then it dies.
However after the period of the slumber, Razgriz returns.
```

ちなみにバックスラッシュなしの下記のような書き方をすると、コードは読みやすいが出力結果に余分な空行が入ってくる。

```python
>>> print("""
...When history witnesses a great change,
... Razgriz reveal itself, first as a dark demon.
... As a demon, it uses its power to rain death upon a land and then it dies.
... However after the period of the slumber, Razgriz returns.
""")

When history witnesses a great change,
Razgriz reveal itself, first as a dark demon.
As a demon, it uses its power to rain death upon a land and then it dies.
However after the period of the slumber, Razgriz returns.

```

## 演算子を用いて文字列を複数回出力する

```python
>>> print('Hi.' * 3)
Hi.Hi.Hi.
```
プラスを用いて文字列を連結することも出来る。

```python
>>> print('Hi.' * 3 + 'Mike.')
Hi.Hi.Hi.Mike.
```

ちなみに、シングルコートで囲まれた部分を文字列と呼んでいたが、「リテラル」という呼び方もある。

## 文字列もといリテラルを連結させる
リテラルはプラスを用いて連結させることが出来る。

```python
>>> print('Py' + 'thon')
Python
```
プラスを用いることなく連結させることもできる。

```python
>>> print('Py''thon')
Python
```

ただし、下記のように一度変数に代入したリテラルは注意が必要。

```python
>>> prefix = 'Py'
>>> print(prefix 'thon')
  File "<stdin>", line 1
    print(prefix 'thon')
                      ^
SyntaxError: invalid syntax
```
プラスを用いれば問題なく連結させることができる。

```python
>>> prefix = 'Py'
>>> print(prefix + 'thon')
Python
```
ところで、リテラルを連結させるユースケースはコード自体を読みやすくする、が主たるものになる。

```python
>>> s = ('aaaaaaaaaaaaaaaaaaa'
...    'bbbbbbbbbbbbbbbbbbb')
>>> print(s)
aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbb
```
長い文章をソースコード上に記述しようとすると、pylint等に「1行は80文字以内にしてや」と怒られるし、実際問題読みにくい。
ちなみに下記のような書き方でも同様の出力結果が得られる。

 ```python
>>> s = 'aaaaaaaaaaaaaaaaaaa' \
...    'bbbbbbbbbbbbbbbbbbb'
>>> print(s)
aaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbb
```
バックスラッシュの用途が意外に多いことに驚きを隠せない。

## リテラルのX番目の文字を表示させる

インデックスを用いることでリテラルのX番目の文字を表示させることができる。

```python
>>> word = 'Python'
>>> print(word[0])
P
```
Pythonをはじめ多くの言語ではインデックス番号は0番目から始まっていく。
ちなみに最後の文字を表示させたいときにwordの文字数をいちいち数えるのは面倒である。したがって下記のようにする。


```python
>>> word = 'Python'
>>> print(word[-1])
n
```
また、Pythonにはスライスというものがある。

```python
>>> word = 'Python'
>>> print(word[0:2])
Py
>>> print(word[2:5])
```
インデックス番号0番目から2番目の手前までの文字、そしてインデックス番号2番めから5番目の手前までの文字を出力できる。

さらに、「インデックス番号の最初から」と「インデックス番号の最後まで」は省略して下記のようにできる。

```python
>>> word = 'Python'
>>> print(word[:2])
Py
>>> print(word[2:])
thon
```
スライスでインデックス番号の最初も最後も省略して書くと下記のようになる。

```python
>>> word = 'Python'
>>> print(word[:])
Python
```



存在しないインデックス番号を指定するとエラーになる。

```python
>>> word = 'Python'
>>> print(word[100])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range
```


## リテラルの一部を書き換える

```python
>>> word = 'Python'
>>> word[0] = 'J'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
```
インデックス番号を指定して上書きしようとしてもエラーになる。
下記のようにすると、結果としてリテラルを書き換えたことになる。

```python
>>> word = 'Python'
>>> word = 'J' + word[1:]
>>> print(word)
Jython
```

## リテラルの長さを出力する
Pythonではlenというメソッドが提供されとり、lenを用いることでリテラルの長さを出力できる。

```python
>>> word = 'Python'
>>> n = len(word)
>>> print(n)
6
```