迷惑メール対策などで、半角英数だけの件名や、それに半角記号を加えて、半角英数記号だけの件名の場合を除きたい、という場合に活躍するのが正規表現。
どのように記述すればよいか
そもそも正規表現ってどんなものか調べてみたことまとめたメモ書きです。
初めて正規表現を使うといった正規表現デビュー者の場合にも、これを読めばばっちり!
(よく分かってない私が簡単に思い出せれるように分かりやすく書いてますので 笑)
Contents
最初に正規表現のまとめから
まず最初に、正規表現の簡単まとめから。
【半角数字のみ】
^[0-9]*$
(空行含む)
^[0-9]+$
(空行除く)
【半角英字のみ】
^[a-zA-Z]*$
(空行含む)
^[a-zA-Z]+$
(空行除く)
【半角記号のみ】
^[ -/:-@[-´{-~]*$
(空行含む)(半角スペースも半角記号として対象)
^[ -/:-@[-´{-~]+$
(空行除く)(半角スペースも半角記号として対象)
半角スペースを半角記号の対象外にする場合については、下方を参照。
【半角すべて】(半角英数記号)
^[ -~]*$
(空行含む)
^[ -~]+$
(空行除く)
どうしてこうした表現になるのか、
これで本当に正しいのか、詳しくは以下で分かりやすく解説してます。
正規表現とは何か簡単に理解
正規表現とはどういうものか、半角英字のみを抽出するパターンを見て確認。
半角英数だけの正規表現は簡単。(検索すればすぐ出てくる)
^[0-9]*$
何を示しているか先頭から順に確認してみると、
この正規表現は以下のような意味になってます。
正規表現 | 意味 |
^ | この直後の文字列が先頭にある場合に一致する |
[ ] | カッコ内に含まれる文字のいずれかに一致する |
0-9 | "-" はカッコ内で使用できる特殊文字で、範囲指定に使われる。 ここでは "0-9" とすることで、0 から 9 までのいずれかが一致する、という意味になる |
* | 直前のパターンの繰り返し。0回も含まれる。 つまりここでは、0から9の文字が全くない、または1つ以上ある場合に一致する。 |
$ | 行の最後に、この直前で指定された文字列がある場合に一致する。 つまりここでは、文字列の最後が 0から9、またはその行が何もない(空行)の場合に一致する |
つまり、まず全体を見ると
^[一致させたいパターン]$
行の先頭( ^ )と行の最後( $ )の間に
「一致させたい文字列のパターン」を
「カッコを使って入れる」
ということになりますね。
一致させたい文字は、ここでは半角数字のみので0から9をカッコとハイフンを使って以下のように指定する。
[0-9]
(これで 0 から 9 のいずれかの文字を抽出する正規表現)
半角数字は、何もないか、1文字以上の文字列の場合、ということで、0回以上の繰り返しの * を付けて
[0-9]*
(これで「何もない空行」、または「0 から 9 のいずれかの文字の繰り返し文字列」を抽出する正規表現)
以上から、半角数字のみの文字列の場合に一致する正規表現は以下になる。
^[0-9]*$
空行であるか、0から9の半角数字だけの行の場合に一致する。
空行は含めず、0から9の半角数字のみの文字列に一致させたい場合には「直前の0回以上の繰り返し」である「*」を「1文字以上の繰り返し」の「+」に変えればOK。
^[0-9]+$
(空行は除いて、「0 から 9 のいずれかの文字の繰り返し文字列」を抽出する正規表現)
半角英字のみ
では同様に半角英数のみの正規表現を見てみると、
[a-zA-Z]
半角アルファベットの小文字の a から z と、大文字の A から Z を指定している形になりますね。
ということで、上で見た半角数字の文字列を抽出する「数字の範囲指定部分」をこちらに置き換えれば、半角英数だけの文字列抽出をする正規表現になる、ってわけですね。
^[a-zA-Z]*$
(「何もない空行」、または「a から z 、AからZ のいずれかの文字の繰り返し文字列」を抽出する正規表現)
空行は除外する、という場合には、同様に「*」を「+」にして以下にすればよいですね。
^[a-zA-Z]+$
(空行を除き、「a から z 、AからZ のいずれかの文字の繰り返し文字列」を抽出する正規表現)
半角記号のみ
続いては半角記号。
半角数字や半角英数と同様にすればよいと分かりますが、記号の範囲はどのように指定するかと見ると、これがちょっとややこしい。
[ -/:-@[-`{-~]
(先頭のカッコの次(ハイフンの前)は半角スペース)
これで正しいの?という感じですが、
半角記号の文字コードの並びはASCIIコード表というもので決まっていて(半角数字や半角英数の並び順もこの表で決まってるのだ)、実際にチェックしてみると記号は以下のように並んでます。
【ASCIIコード表】
1行目は見出し行。(なので気にしない)
2行目以降で色を付けたところが半角記号
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
SP | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
@ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
´ | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | DL |
この表中、左上の「SP」は半角スペース。
(スペースは見えないので、便宜上 分かりやすいように SP と文字表記してるだけ)
右下の「DL」は 制御文字と呼ばれるものの1つで「DEL」。
(こちらも分かりやすいように文字表記してるだけ)
上の表を見て分かるように、
半角記号は以下の4つのパートに分かれて配置されてます。
- 1)薄いオレンジ箇所: スペース から「 / 」
- 2)薄い赤色箇所:「 : 」から「 @ 」
- 3)ブルー箇所:「 [ 」から「 ´ 」
- 4)薄いグリーン箇所:「 { 」から「 ~ 」
英字の場合、A-Z, a-z の2つを指定したけど、
記号の場合はこの4パターンを指定する必要がある。
- 1)スペース から「 / 」: -/
- 2)「 : 」から「 @ 」: :-@
- 3)「 [ 」から「 ´ 」: [-´
- 4)「 { 」から「 ~ 」: {-~
この4つを並べれば良いですね。
[ -/:-@[-´{-~]
であとは半角数字や英字と同様で、
結果、半角記号のみの文字列に一致する正規表現は以下になります。
^[ -/:-@[-´{-~]*$
(空行も一致)
スペースは省いた半角記号のみの文字列を対象にしたい場合には、正規表現は以下のようになりますね。
^[!-/:-@[-´{-~]*$
(先頭から2つ目にあるカッコの次の半角スペースを「!」に変えただけ)
半角英数、半角記号すべて
最後に、ここまで見た半角英数、半角記号すべてを対象にする正規表現です。
もともと上でみた正規表現3つ全てをくっつければ良いかと、まさに今ここで書いている瞬間まで思って調べながら書いてましたが、先ほど見た ASCIIコード表を改めて見てみると...
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
SP | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
@ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
´ | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | DL |
半角英数記号すべて、であれば、
わざわざ数字、英字、記号、と分けて考えなくても、左上のSP(半角スペース)から右下の「~」までを範囲にすればいいじゃん、というところですね。
半角文字全てということになりますが、その正規表現は非常にシンプルで以下。
^[ -~]*$
(半角スペースを含めて、半角英数記号の文字列を抽出する正規表現。空行も抽出。)
これまで同様に、空行は対象外にするには「*」を「+」に置き換えて、
^[ -~]+$
また半角スペースは対象にしない場合には、
左から2番目のカッコの次の半角スペースを「!」にすれば良いですね。
^[!-~]*$
こちらも空行を対象外にするには以下になります。
^[!-~]+$
(「*」を「+」に置き換えただけ)
やっと正規表現の片鱗が理解できた感じです。
お役に立てたら幸いです!