PHPしか知らない僕がPythonを少し触ってみたよ 〜文字列操作の捜査〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
プログラマの捜査は検索です

この記事を三行にまとめると

代表的(?)なのをいくつか調べてみました
だいたいPythonでもできると思って良いんじゃないでしょうか
「strip_tags()」に相当するものがないのがちょい悔しかった
文字列を操作する関数ってPHPでもPythonでもいっぱいあると思うんですけど、全部は紹介しきれないので、代表的(?)なのをいくつか調べてみました。

だいたいPHPでもできることはPythonでもできると思って良いんじゃないでしょうか。substr()とかstrlen()とかに対応するものはPythonにもちゃんとあります。



substr

まずは基本的な文字の切り取りから。

//PHP
$s = 'norm-nois.com';
echo substr($s, 0, 4);

#Python
s = 'norm-nois.com'
print(s[0:4])

「norm-nois.com」という文字列の先頭の4文字(norm)を取得しています。上記の場合、結果は同じですが、PHPの方は「0番目から4バイト分を切り取る」という動きなのに対し、Pythonは「0番目から4番目の手前までを切り取る」という動きをしています。

何か言葉だとややこしいかもだけど、各文字が何番目かってのは以下の通りです。

+---+---+---+---+---+---+---+---+---+---+----+----+----+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
+---+---+---+---+---+---+---+---+---+---+----+----+----+
| n | o | r | m | - | n | o | i | s | . |  c |  o |  m |
+---+---+---+---+---+---+---+---+---+---+----+----+----+

だから例えば「norm-nois.com」の「nois」(5番目から8番目まで)を切り取りたい場合はこうなる。

//PHP
substr($s, 5, 4);

#Python
s[5:9]

「s[5:4]」みたいに書くと一文字も切り取れないので注意。マイナスをつけた場合は後ろから数えます。他にも片方の数字を省略した書き方もできる。

s = 'norm-nois.com'
print(s[5:-4]) #nois
print(s[5:]) #nois.com
print(s[:5]) #norm-



マルチバイトの場合、PHPだとmb_substr()を使う必要がありますが、Pythonには特にそういうのはないです。

s ='あかつきのお宿'
print(s[0:4])

#出力結果
あかつき



strpos

「norm-nois.com」の文字列からピリオドが何バイト目にあるか調べてみます。

//PHP
$s = 'norm-nois.com';
echo strpos($s, '.');

#Python
s = 'norm-nois.com'
print(s.find('.'))

これもマルチバイトの場合、PHPだとmb_strpos()を使いますが、Pythonはどっちもfind()でOKです。

文字列にない文字を指定した場合、strpos()はfalseが返ってきますが、find()は-1が返ってきます。

//PHP
$s = 'norm-nois.com';
echo strpos($s, 'a');//false

#Python
s = 'norm-nois.com'
print(s.find('a')) #-1

Pythonの場合、他にも「index()」というメソッドを使っても似たような操作ができますが、index()の場合は存在しない文字列を指定するとエラーになってしまうので注意が必要です。

s = 'norm-nois.com'
print(s.index('.')) #9
print(s.index('a')) #エラー

index()は配列にも使えるので、PHPの「array_search()」みたいな処理も可能です。でもエラーが返ってきてほしくないなら、文字列の時はfind()を使えば良いと思います。

文字列に特定の文字が含まれているかどうかを判定するだけならin演算子ってのもあります。

s = 'norm-nois.com'
print('.' in s) #true
print('a' in s) #false

in演算子はindex()と同じように配列でも使えるので、その時にまた触れましょう。



strrpos

「norm-nois.com」の文字列から最後の「o」が何バイト目かを取得してみます。

//PHP
$s = 'norm-nois.com';
echo strrpos($s, 'o');

#Python
s = 'norm-nois.com'
print(s.rfind('o'))

これも存在しない文字を指定した場合は、strrpos()はfalse、rfind()は-1が返ってきます。



strlen

「norm-nois.com」が何バイトか調べてみます。

//PHP
$s = 'norm-nois.com';
echo strlen($s);

#Python
s = 'norm-nois.com'
print(len(s))

くどいようですが、マルチバイトの場合は、PHPならmb_strlen()が必要ですが、Pythonはlen()でオッケーです。



substr_count

「norm-nois.com」の文字列の中に「o」が何文字含まれているか知りたい場合。

//PHP
$s = 'norm-nois.com';
echo substr_count($s, 'o');

#Python
s = 'norm-nois.com'
print(s.count('o'))

マルチバイトの場合はP(以下略)



strtoupper、strtolower

アルファベットを全て大文字にする場合や小文字にする場合。

//PHP
$s = 'norm-nois.com';
echo strtoupper($s);//全部大文字
echo strtolower($s);//全部小文字

#Python
s = 'norm-nois.com'
print(s.upper()) #全部大文字
print(s.lower()) #全部小文字



ucfirst、lcfirst

文字列の先頭の一文字を大文字にしたり小文字にしたり。

//PHP
$s = 'norm-nois.com';
echo ucfirst($s);//先頭を大文字
echo lcfirst($s);//先頭を小文字

#Python
s = 'norm-nois.com'
print(s.capitalize()) #先頭を大文字

PHPは先頭の一文字を大文字にするものと小文字にするものの両方がありますが、Pythonは大文字にするやつしかないっぽいです。



trim

文字列の先頭や末尾にある空白を除去してみます。

//PHP
$s = '   norm-nois.com   ';
echo trim($s);

#Python
s = '   norm-nois.com   ';
print(s.strip())



is_numeric

文字列が全部数字がどうかを判定します。

//PHP
$s = '12345';
var_dump(is_numeric($s));//true

#Python
s = '12345'
print(s.isdigit()) #true

Pythonの「isdigit()」は文字列型じゃないとエラーになります。int型に使うとエラーになる。まあ、int型なら確実に数字のはずだから、使う必要ないんですけどね。

//PHP
$s = 12345;
var_dump(is_numeric($s));//true

#Python
s = 12345
print(s.isdigit()) #エラー

PHPは「is_numeric()」の他に「ctype_digit()」というのもありますが、僕はあまり使ったことないかな……。



ctype_alpha

文字列が全部アルファベットかどうかを判定します。

//PHP
$s = 'norm-nois.com';
var_dump(ctype_alpha($s));//false

#Python
s = 'norm-nois.com';
print(s.isalpha()) #false

「norm-nois.com」だとアルファベットの他にハイフンやピリオドが入ってるので、この場合はfalseになりますね。「normnoiscom」ならtrueになる。

isalpha()もint型とかには使えません。ctype_alphaはint型でも大丈夫。



ctype_alnum

文字列が全部英数字だけかどうかを判定するものもあります。

//PHP
$s = 'normnois12345';
var_dump(ctype_alnum($s));//true

#Python
s = 'normnois12345';
print(s.isalnum()) #true

しつこい男は嫌われるらしいが、あえて言おう。isalnum()はint型に使うとエラーになると。



is_int、is_string

PHPはそんなに型を気にしなくても大丈夫なことが多いですが、Pythonだと型のせいでうっかりエラーを出してしまうかもしれないんで、int型とかstring型とか判定するケースもあるかもしれません。

//PHP
$s = 12345;
var_dump(is_int($s)));//true
var_dump(is_string($s)));//false

$s = '12345';
var_dump(is_int($s)));//false
var_dump(is_string($s)));//true

#Python
s = 12345
print(isinstance(s, int)) #true
print(isinstance(s, str)) #false

s = '12345'
print(isinstance(s, int)) #false
print(isinstance(s, str)) #true

PHPだと配列かどうか調べたりする場合にもis_array()だのis_object()だのと分かれていますが、Pythonはisinstance()だけで配列とかの型も判定できます。javascriptのtypeofとかに近い感覚なのかな?






今回はこれくらいにしておきましょうか。もうちょいコンパクトにするつもりでしたが、いつものごとく長くなっちまったい。

マルチバイトに関してはほとんど触れなかったので、文字コードに関するやつとかURLのエンコードみたいなのはまたの機会にしましょう。あと正規表現も。

個人的には、HTMLタグを除去する「strip_tags()」に相当するものがPythonにないのがちょい悔しかったです。あいつ意外と良い働きするんだけどなー。探し方が悪かったのかな? 僕が見つけられなかっただけで実はあるぞーって場合には、ぜひともご一報いただきたいです。



その他のPythonを少し触ってみたの記事はこちら
前書きと索引的な
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください