# String
陳以哲 onion
credit: 2024 Py 簡報
---
## 什麼是 string?
----
其實大家早就用過了
```python
print("Hello world")
```
----
字串是被單引號或雙引號包起來的一串文字
```python
string1 = 'I am a string'
string2 = "I am a string, too"
```
----
那這是個對的字串嗎?
```python
'I'm a valid string?'
```

<!-- .element: class="fragment" data-fragment-index="1" -->
----
怎麼解決?
```python
string3 = "I'm a valid string"
```
可以,但最好用「跳脫字元」
---
## 跳脫字元
----
有些符號沒辦法打出來,或是本身帶有其他意義。
i.e. 換行、tab、引號...
----
使用反斜線 `\` 來表示
```
\n 換行
\t tab
\' 單引號
\" 雙引號
\\ 反斜線
...
```
----
剛剛字串內要引號的問題:
```python=
string1 = "I'm a bad solution"
string2 = "I\'m a better solution"
string3 = 'I\'m good, too'
```
---
## 字串基本操作
----
### 多行字串
```python
a = '''This
is a
multiple-line
string'''
```
在編輯器換行就相當於字串裡面有一個 `\n`
----
多行字串可以當作註解
```python
'''
merkle-dir.sh - A tool for working with Merkle trees of directories.
Usage:
merkle-dir.sh <subcommand> [options] [<argument>]
merkle-dir.sh build <directory> --output <merkle-tree-file>
'''
```
----
### f-string
```
str1 = "sprout"
num1 = "14"
print(f"Today\'s {str1} starts at {num1} o\'clock")
# Today's sprout starts at 14 o'clock
print(f"{str1=}")
# str1='sprout'
```
----
### 練習
上週作業 [卍九九乘法改乂](https://tioj.sprout.tw/problems/729) 想必大家輸出很辛苦?
試試看用 f-string 輸出吧
----
### 字串運算
```python
print("str1" + "str2") # str1str2
print("str1" > "str2") # False, 按照字典序比
print("aaaa" > "aaa") # True, 都一樣就比長度
print("str1" * 3) # str1str1str1
```
----
### len
得到字串長度
```
print(len("sprout python"))
# 13
```
其實不只字串,`len` 可以拿 list 等等物件的長度
---
### indexing
----
方括號裡面放想要第幾個字元
```
string = "abcdefg"
print(string[0]) # a
print(string[3]) # d
print(string[-1]) # g
```
----
可以指定範圍
`string[start:end:step]`
```
string = "abcdefg"
print(string[0:3]) # abc
print(string[:3]) # abc
print(string[3:]) # defg
print(string[::3]) # adg
```
----
### 用 for 取值 (iterable)
```python
string = "sprout"
for c in string:
print(c, end=" ")
# s p r o u t
```
---
## 跟 list 不太一樣的地方
----
在 C 語言裡面
字串其實就是一堆字元組成的 list/array
但 Python 不太一樣
----
### string is not list
```
string = "sprout"
char_list = ['s', 'p', 'r', 'o', 'u', 't']
print("sp" in string) # True
print("sp" in char_list) # False
```
----
### Immutable
Mutable may cause trouble!
[補充 1](https://www.geeksforgeeks.org/why-are-python-strings-immutable/) [補充 2](https://stackoverflow.com/questions/8680080/why-are-python-strings-immutable-best-practices-for-using-them)
```
string = "sprout"
string[0] = "S" # TypeError
```
想要改字怎麼辦?
----
### 練習
對於 "abcdefg"
輸出第 $i$ 行把第 $i$ 個字元換成 `*`
```
*bcdefg
a*cdefg
ab*defg
abc*efg
abcd*fg
abcde*g
abcdef*
```
---
## String Methods
----
基本上[多到講不完](https://www.w3schools.com/python/python_ref_string.asp)
----
你可以...
- python string reverse
- python string sort
- python string all letters
- 或是現代問題用現代方法解決
---
### `strip()`
十分好用,[doc](https://docs.python.org/3.4/library/stdtypes.html#str.strip)
把行頭行尾的空格、換行去掉
```python=
string = " sprout \n"
print(string) # 前後兩個空格加換行
print(string.strip()) # 沒有空格沒有換行
```
----
`strip()` 裡面可以放要去掉的字元
default 空白+換行
```python=
domain = 'www.example.com'
print(domain.strip('cmowz.'))
# example
```
---
### `split()`
十分好用,[doc](https://docs.python.org/3.4/library/stdtypes.html#str.split)
把字串用字元切割,default 「任意個空白」
```
print("s p r o u t".split())
# ['s', 'p', 'r', 'o', 'u', 't']
```
----
`split()` 可以指定用來切割的字元
但可能出現空字串喔
```python
print('1,2,3'.split(','))
# ['1', '2', '3']
print('1,2,,3,'.split(','))
# ['1', '2', '', '3', '']
```
----
`split()` 跟 `split(" ")`
好像有微妙的不同?
```python
print("1 2 3".split())
print("1 2 3".split(" "))
```
----
所以你現在知道要怎麼在 Sprout OJ 上輸入了
很常就是組合技
```python
my_list = input().strip().split()
```
---
### `join()`
十分好用,把 list 內的元素串成字串
基本上是 `split()` 的相反
```python
my_list = ["sp", "rout"]
print("".join(my_list)) # sprout
print(" ".join(my_list)) # sp rout
```
----
`string.join(words)`
- 用 string 把 word 裡面的元素串起來
- words 必須是 list 等 iterable
- words 裡面必須全是字串
---
### `find()`
找子字串在哪個 index
```python
string = "This is string"
print(string.find("str")) # 8
```
----
`string.find(value, start, end)`
- value: 想找什麼
- start: 開始的 index,default 0
- end: 找到哪個 index,default 尾巴
- 回傳第一個找到的 index,找不到回傳 -1
```python
string = "This is string1, this is string2"
print(string.find("str")) # 8
```
---
### `is 家族`
```python
print("119".isdigit()) # True
print("Hello".isalpha()) # True
print("Hello, it's me".isalpha()) # False
print("C8763".isalnum()) # True
```
----
`is` 系列有很多
當然你也可以自己寫
```python
string = "sprout"
low_flag = True
for c in string:
if not ord("a") <= ord(c) <= ord("z"):
low_flag = False
print(f"is all lowercase: {low_flag}")
```
---
### `upper()`、`lower()`
把字串變成全大/小寫
```python
string = "Sprout"
string.upper() # SPROUT
string.lower() # sprout
```
---
### `replace(old, new)`
把字串內 `old` 都換成 `new`
```python
string = "I am a student. I am also a coder"
string = string.replace("I", "You")
string = string.replace("am", "are")
# You are a student. You are also a coder
```
---
### 練習
第一行輸入一段[歌詞](https://tioj.sprout.tw/contests/8/problems/1011) $l$
第二行輸入兩個字串 $a$、$b$
請輸出 $a$ 在 $l$ 內出現多少次
並把 $l$ 當中的所有 $a$ 換成 $b$
----
[Problem 1011](https://www.youtube.com/watch?v=xvFZjo5PgG0)
```
Never gonna give you up. Never gonna let you down. Never gonna run around and desert you
Never Always
```
```
3
Always gonna give you up. Always gonna let you down. Always gonna run around and desert you
```
---
### 一些大實話
會忘記各個 method 語法沒關係
知道怎麼查、有什麼可以用就好
---
### Homework
- [706](https://tioj.sprout.tw/contests/8/problems/706)
- [740](https://tioj.sprout.tw/contests/8/problems/740)
----
## Thank You
{"title":"Python String","contributors":"[{\"id\":\"069820a6-3e96-4d49-99f2-2503b2c47d84\",\"add\":5967,\"del\":293}]","description":"陳以哲, credit: 2024 Py 簡報"}