はじめに
正規表現を学び始めたので、習作に書いてみました。
ここでの「英文」の定義は以下とします。
- アルファベット(A~Z, a-z)と半角数字(0~9)、アポストロフィ(')で構成される
- 単語の区切りに1文字の空白文字を挟む
- 文の終わりにピリオド(.)、エクスクラメーション(!)、クエスチョン(?)をつける
文法として成り立ってる!というものではないので注意。(それはそれで面白そうだけど)
結果
import re
s = input()
p = r"^([A-Z|a-z|0-9|']+\s)*[A-Z|a-z|0-9|']+[.|!|?]$"
if re.search(p, s):
print("Yes")
else:
print("No")
うーん、ゴツい。
説明
p = r"^([A-Z|a-z|0-9|']+\s)*[A-Z|a-z|0-9|']+[.|!|?]$"
まずはわかりやすいところから。
^, $(文頭・末尾の一文字を指定する)
それぞれ^<文字>
, <文字>$
を文頭、末尾につけることで指定できます。
+, *(n文字以上の連続した文)
<文字>+
, <文字>*
でn文字以上の、指定した文字で構成された文となります。
*
は0文字以上(なくてもOK)+
は1文字以上(ないとNG)という意味。
[](文字の指定)
[<文字>]
とすることで、使用できる文字を限定できます。文字列でも可。
パイプ(|
)で区切ることで複数指定も可能。
文中で使っている[A-Z|a-z|0-9|']
は「アルファベット(A~Z, a-z)と半角数字(0~9)、アポストロフィ(')だけしか使えないよ」って感じ。
\s(空白文字)
空白はコードでは表しづらいので、かわりに\s
を使います。いわゆるエスケープシーケンス。
かわりに半角文字を使っても大丈夫ですが、個人的にはう~んって感じです。
要約
ようやく全部終えたところで、あらためて見てみます。
p = r"^([A-Z|a-z|0-9|']+\s)*[A-Z|a-z|0-9|']+[.|!|?]$"
分解して考えていきましょう。
-
英文を「
[単語+空白] *n + 単語 (+ 記号)
」として考える
This is a null.
という例文を考えます。
このとき、This
、is
、a
の3つは「単語+空白」というパターンを持ってることがわかります。これを正規表現で表すとこんな感じ。
^([A-Z|a-z|0-9|']+\s)*
1単語が
[A-Z|a-z|0-9|']+
に相当します。 -
最後の単語と記号を認識
とくに言うことなしです。以下の通り。
[A-Z|a-z|0-9|']+[.|!|?]$
実行してみる
テストケースと結果を見ていきます。
This is a pen.
> Yes
ルールに従っている文なので、しっかり認識します。
This is a pen
No
末尾に記号が入っていないので弾かれてしまいました。
これはペンです.
No
当然日本語は弾きます。
ThIs Is A pEn.
Yes
大文字小文字がバラバラでも認識します。まあいいや。
Kore Ha Pen Desu.
Yes
エセ英語も通してしまいます。要改善。
おわりに
複雑そうで避けていた正規表現ですが、意外と面白そうでした。
使用頻度も高そうなので習得しておきたい。