Python文字列の比較や変換

# はじめに
Pythonで文字比較・文字列変換について、文法、関数、正規表現などをまとめてみた。

# 目次
+ [文字列比較](#文字列比較) 
+ [文字列分割](#文字列分割)
+ [文字列変換・削除](#文字列変換削除)
+ [数値文字列→時間変換](#数値文字列時間変換)
+ [正規表現](#正規表現)



## 文字列比較
if文にて、文字列を比較する。
手段|意味
---|---
A == B<br> A != B|完全一致確認。結果がTrue/Falseで返却される。
A in B<br> A not in B|一部一致。AがBに含まれるか否か。結果がTrue/Falseで返却される。
str_data.startswith(A,[start][,end])|先頭一致。startとendで開始、終了位置を指定できる。省略も可。
str_data.endswith(A,[start][,end])|後方一致。startとendで開始、終了位置を指定できる。省略も可。
re.search(r"A",str_data)):|正規表現一致。一致した場合は、re.Matchオブジェクトを返却する。一致しない場合はNoneになる。re.searchの使い方は[こちら](https://qiita.com/tapitapi/items/f20b1033b5379982e9e5)。



```python:example.py
str_data = "abcdeABCDEあいうえお01234"

if("abcdeABCDEあいうえお01234" == str_data):
	print(f'# (1)if("abcdeABCDEあいうえお01234" == str_data):True')
if("abcdeABCDEあいうえお" != str_data ):
	print(f'# (2)if("abcdeABCDEあいうえお" != str_data ):True')
if("あいうえお" in  str_data):
	print(f'# (3)if("あいうえお" in  str_data):True')
if("かきくけこ" not in  str_data):
	print(f'# (4)if("かきくけこ" not in  str_data):True')

# (1)if("abcdeABCDEあいうえお01234" == str_data):True
# (2)if("abcdeABCDEあいうえお" != str_data ):True
# (3)if("あいうえお" in  str_data):True
# (4)if("かきくけこ" not in  str_data):True
```
```python:example.py
str_data = "abcdeABCDEあいうえお01234"

# 先頭から"abcd"で始まる文字列
if(str_data.startswith("abcd")):
	print(f'# (5)if(str_data.startswith("abcd")):True')
# 先頭から10文字目から"あいう"で始まる文字列
if(str_data.startswith("あいう",10)):
	print(f'# (6)if(str_data.startswith("あいう",10)):True')
# 後方が"01234"で終わる文字列
if(str_data.endswith("01234")):
	print(f'# (7)if(str_data.endswith("01234")):True')
# 後方から5文字目が"あいうえお"で終わる文字列(0,-5は、0文字目から後ろの5文字目までが検索対象)
if(str_data.endswith("あいうえお",0,-5)):
	print(f'# (8)if(str_data.endswith("あいうえお",-5)):True')

# (5)if(str_data.startswith("abcd")):True
# (6)if(str_data.startswith("あいう",10)):True
# (7)if(str_data.endswith("01234")):True
# (8)if(str_data.endswith("あいうえお",-5)):True
```
```python:example.py
import re

str_data = "abcdeABCDEあいうえお01234"

if(re.search(r"abcd.*1234",str_data)):
	print(f'# (9)if(re.search(r"abcd.*1234",str_data)):True')

# (9)if(re.search(r"abcd.*1234",str_data)):True
```
[戻る](#目次)

## 文字列分割
文字列を特定文字や文字数で分割する。
手段|意味
---|---
str_data.split('A', [num])|文字列Aで分割する。numで繰り返し回数の指定をする。
str_data.partition('A')|文字列Aで3分割する。
 re.split(r'A', str_data, [num])|正規表現Aで分割する。numで繰り返し回数の指定をする。
[str_data[i:i+3] for i in range(0, len(str_data), 3)] |指定文字数で分割する。スライスと内包表記を使う。例は3文字ずつ分割。内包表記は[こちら](https://qiita.com/tapitapi/items/30b9ee4d8b80b03741f5)。
 
```python:example.py
str_data = "01,23 45@67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD"

# 特定の文字列で分割 split()
split_list_1 = str_data.split(',')
split_list_2 = str_data.split(' ')
split_list_3 = str_data.split('@')
split_list_4 = str_data.split('abcd')

print(f'# {split_list_1=}\n# {split_list_2=}\n# {split_list_3=}\n# {split_list_4=}\n')

# split_list_1=['01', '23 45@67.89-abcd=ABCD|01', '23 45@67.89-abcd=ABCD']
# split_list_2=['01,23', '45@67.89-abcd=ABCD|01,23', '45@67.89-abcd=ABCD']
# split_list_3=['01,23 45', '67.89-abcd=ABCD|01,23 45', '67.89-abcd=ABCD']
# split_list_4=['01,23 45@67.89-', '=ABCD|01,23 45@67.89-', '=ABCD']
```
```python:example.py
str_data = "01,23 45@67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD"

# 特定の文字列で3分割 partition()
split_list_1 = str_data.partition(',')
split_list_2 = str_data.partition(' ')
split_list_3 = str_data.partition('@')
split_list_4 = str_data.partition('abcd')

print(f'# {split_list_1=}\n# {split_list_2=}\n# {split_list_3=}\n# {split_list_4=}\n')

# split_list_1=('01', ',', '23 45@67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD')
# split_list_2=('01,23', ' ', '45@67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD')
# split_list_3=('01,23 45', '@', '67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD')
# split_list_4=('01,23 45@67.89-', 'abcd', '=ABCD|01,23 45@67.89-abcd=ABCD')
```
```python:example.py
str_data = "01,23 45@67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD"

# 正規表現で分割 re.split()
split_list_1 = re.split(r'[\,\ \@\.\-\=\|]',str_data)	# , @.-=| で分割
split_list_2 = re.split(r'\W',str_data)					# 任意の英数字以外で分割
split_list_3 = re.split(r'\W',str_data,3)				# 任意の英数字以外で分割 3回
split_list_4 = re.split(r'ab|AB',str_data)				# abかABで分割

print(f'# {split_list_1=}\n# {split_list_2=}\n# {split_list_3=}\n# {split_list_4=}\n')

# split_list_1=['01', '23', '45', '67', '89', 'abcd', 'ABCD', '01', '23', '45', '67', '89', 'abcd', 'ABCD']
# split_list_2=['01', '23', '45', '67', '89', 'abcd', 'ABCD', '01', '23', '45', '67', '89', 'abcd', 'ABCD']
# split_list_3=['01', '23', '45', '67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD']
# split_list_4=['01,23 45@67.89-', 'cd=', 'CD|01,23 45@67.89-', 'cd=', 'CD']
```
```python:example.py
str_data = "0123456789abcdefghABCDEFGHあいうえおかきくけこ"

# 文字数で分割
split_list_1 = [str_data[i:i+3] for i in range(0, len(str_data), 3)]

print(f'# {split_list_1=}')

# split_list_1=['012', '345', '678', '9ab', 'cde', 'fgh', 'ABC', 'DEF', 'GHあ', 'いうえ', 'おかき', 'くけこ']
```
[戻る](#目次)

## 文字列変換・削除
```re.sub()```を使って、文字列変換や削除をする。```re.sub()```の使い方は[こちら](https://qiita.com/tapitapi/items/d0dda807fbc04df850b6)。

### 任意区切り文字削除。変換後を```''```にする。
```python:example.py
str_data = "01,23 45@67.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD"

#任意の区切り文字削除
rep_data_1 = re.sub(r'\W','',str_data)		# 任意の英数字以外の文字列を削除
rep_data_2 = re.sub(r'\W','',str_data,3)	# 任意の英数字以外の文字列を削除 3回
print(f'# {rep_data_1=}\n# {rep_data_2=}')

# rep_data_1='0123456789abcdABCD0123456789abcdABCD'
# rep_data_2='01234567.89-abcd=ABCD|01,23 45@67.89-abcd=ABCD'
```

### 任意区切り文字を統一。一致文字列は```|```で並べる。
```python:example.py
str_data = "0000,11111=/0000111100001111_0000111100001111.00001111	00001111acdc00001111"

#区切り文字を,に統一
rep_data_1 = re.sub(r',|=/|_| |\t|\.|abcd',',',str_data)
print(f'# {rep_data_1=}')

# rep_data_1='0000,11111,0000111100001111,0000111100001111,00001111,00001111acdc00001111'
```


### 最短マッチ抜き出し。```?```を使う。
```python:example.py
# eで終わる文字を抜き出す-----------------------------------------------
str_data = "0123456789abcde0123456789abcde0123456789abcde0123456789"

rep_data_1 = re.sub(r'(.*e)(.*)',r'\1',str_data)		# eで終わる文字を抜き出す
rep_data_2 = re.sub(r'(.*?e)(.*)',r'\1',str_data)		# eで終わる文字を抜き出す最短
print(f'# {rep_data_1=}\n# {rep_data_2=}')

# rep_data_1='0123456789abcde0123456789abcde0123456789abcde'
# rep_data_2='0123456789abcde'

# <>の文字を抜き出す---------------------------------------------------
str_data = "<abcde>0123456789<ABCDE>0123456789<あいうえおか>0123456789"

rep_data_1 = re.sub(r'(<.*>)(.*)',r'\1',str_data)		# <>の文字を抜き出す
rep_data_2 = re.sub(r'(<.*?>)(.*)',r'\1',str_data)		# <>の文字を抜き出す最短
print(f'# {rep_data_1=}\n# {rep_data_2=}')

# rep_data_1='<abcde>0123456789<ABCDE>0123456789<あいうえおか>'
# rep_data_2='<abcde>'
```
[戻る](#目次)

## 数値文字列→時間変換
通信ログなど、msやusの数値文字列を時刻文字列に変換。
```python:example.py
#10進数 ms
time_str='12345678'
time=int(time_str)
print(f'# {int(time/(1000*60*60*24))}days:{int(time/(1000*60*60))%24:02}:{int(time/(1000*60))%60:02}:{int(time/1000)%60:02}.{time%1000:03}ms')
# 0days:03:25:45.678ms

#16進数 ms
time_str='0x1234ABCD'
time=int(time_str, 16)
print(f'# {int(time/(1000*60*60*24))}days:{int(time/(1000*60*60))%24:02}:{int(time/(1000*60))%60:02}:{int(time/1000)%60:02}.{time%1000:03}ms')
# 3days:12:50:41.741ms

#10進数 us
time_str='12345678123'
time=int(time_str)
print(f'# {int(time/(1000*1000*60*60*24))}days:{int(time/(1000*1000*60*60))%24:02}:{int(time/(1000*1000*60))%60:02}:{int(time/(1000*1000))%60:02}.{int(time/1000)%1000:03}.{time%1000:03}us')
# 0days:03:25:45.678.123us

#16進数 us
time_str='0x1234ABCD123'
time=int(time_str, 16)
print(f'# {int(time/(1000*1000*60*60*24))}days:{int(time/(1000*1000*60*60))%24:02}:{int(time/(1000*1000*60))%60:02}:{int(time/(1000*1000))%60:02}.{int(time/1000)%1000:03}.{time%1000:03}us')
# 14days:11:31:47.371.427us
```
[戻る](#目次)

## 正規表現
### 基本の正規表現
正規表現|内容
---|---
\d|任意の数字
\D|任意の数字以外			
\s|任意の空白文字			
\S|任意の空白文字以外			
\w|任意の英数字			
\W|任意の英数字以外
.|任意の一文字
^|文字列の先頭  **^abc (abcで始まる)**
$|文字列の末尾  **abc$ (abcで終わる)**
*|０回以上の繰り返し
+|１回以上の繰り返し
?|０回または１回。最短マッチにも使う。
{m}|m回の繰り返し
{m,n}|m〜n回の繰り返し
\||or
[]|or  **[abcdef] (a,b,c,d,e,fのどれか)**
()|グループ化

### 正規表現例
正規表現例|内容
---|---
[0-9]+|数字列
[０-９]+|全角数字列
[0-9\|０-９]+|半角全角数字列
[a-z]+|アルファベット小文字列
[A-Z]+|アルファベット大文字列
[a-z\|A-Z]+|アルファベット大文字小文字列
[0-9]{4}|数字桁数指定(例 4桁)
[0-9]{1-4}|数字桁数範囲指定(例 1～4桁)
<.*>|<>で囲まれた文字。
<.*?>|<>で囲まれた最短。


[戻る](#目次)


以上