概要
タイトルのまま
version
ruby | 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux] |
irb | 1.0.0 (2018-12-18) |
半角の正規表現
この記事を参考にしました!
Rubyで全角半角を判定
半角1文字のマッチング
上記記事によると、
-
-~
... ASCII -
-~。-゚
... 半角文字
ということらしいので早速試してみる
'ア'.match /[ -~。-゚]/
=> #<MatchData "ア">
'abcあいう'.match /[ -~。-゚]/
=> #<MatchData "a">
最初にmatchした1文字だけを検出してくれる
半角のみであること
'アアア'.match /\A[ -~。-゚]+\z/
=> #<MatchData "アアア">
'abc'.match /\A[ -~。-゚]+\z/
=> #<MatchData "abc">
'abcあいう'.match /\A[ -~。-゚]+\z/
=> nil
'abcあいうd'.match /\A[ -~。-゚]+\z/
=> nil
正規表現の最初に (←間違いでした。理由は補足を参照)^
を、最後に +$
をつけることで、最初から最後まで全ての文字が正規表現にmatchするかどうかを判定してくれる。
正規表現の最初に \A
を、最後に +\z
をつけることで、最初から最後まで全ての文字が正規表現にmatchするかどうかを判定してくれる。
"半角のみ" かつ "日本語を含まない" こと
半角カタカナなんていらないがや。
'アアア'.match /\A[ -~]+\z/
=> nil
'abc'.match /\A[ -~]+\z/
=> #<MatchData "abc">
'abcあいう'.match /\A[ -~]+\z/
=> nil
'+*`{}=~<>?_)(;:@,./"\\'.match /\A[ -~]+\z/
=> #<MatchData "+*`{}=~<>?_)(;:@,./\"\\">
全部は試してないけど、記号も大丈夫そう。
ただ、このままだと半角スペースも許容してしまう。
' '.match /\A[ -~]+\z/
=> #<MatchData " ">
' '.match /\A[ -~]+\z/
=> nil
この通り。
この時点で全角スペースは拒否できてる。
スペースを除外
"半角のみ"かつ"日本語を含まない"かつ"スペースを含まない"こと
scivola
さんのおかげで判明しましたが、C0 Controls and Basic Latin によると、Unicodeの文字の順番的には以下のようになっているので、
0020 | 0021 | 0022 | 0023 | ... | 0079 | 007A | 007B | 007C | 007D | 007E |
---|---|---|---|---|---|---|---|---|---|---|
半角スペース | ! | " | # | .... | y | z | { | | | } | ~ |
-~
ではなくて!-~
にすればスペースを除外できるとのこと。
早速試してみる。
# これだと半角スペースもマッチしてしまうが...
'abc ef'.match /\A[ -~]+\z/
=> #<MatchData "abc ef">
# ! に変えればマッチしない^^
'abc ef'.match /\A[!-~]+\z/
=> nil
よしよし(^ワ^)
こんな記述量で簡単に実現できるんですね。
おまけ ~複数の正規表現で同時にチェックする~
以前、せっかく正規表現のAND演算の方法を見つけたのでここに残しておく。
ただ単に、複数の正規表現演算の結果を &&
演算子で繋ぐだけ。
def half_nojapanese_nospace?(str)
(str.match /\A[ -~]+\z/) && (str.match /\A[^[:space:]]+\z/)
end
good_str = 'abc*'
half_nojapanese_nospace?(str)
=> #<MatchData "abc*">
bad_str1 = 'abcあいう'
half_nojapanese_nospace?(str)
=> nil
bad_str2 = 'abc *+'
half_nojapanese_nospace?(str)
=> nil
より良く
match
をmatch?
にすると、結果をtrue
orfalse
で返してくれるようにもなります^^
def half_nojapanese_nospace?(str)
(str.match? /\A[ -~]+\z/) && (str.match? /\A[^[:space:]]+\z/)
end
half_nojapanese_nospace?('*@abc~')
=> true
half_nojapanese_nospace?('*@abc ~')
=> false
こんな感じ。
補足
以前は理解しておらず誤った情報を記載していましたが、以下の点が間違っているようでした。
scivola
さんご指摘ありがとうございます!
-
(文字列).match /^[正規表現の条件]+$/
... × (← 今回の用途には使えない )
理由: 文字列内に 改行文字 が含まれる場合、どれか一つの行が正規表現にマッチしさえすれば、チェックを通過してしまうため
# 1行目 abc
# 2行目 あ
# という風に分かれてしまい、1行目の abc だけが正規表現にマッチしてしまう例
"abc\nあ".match /^[ -~。-゚]+$/
=> #<MatchData "abc">
# ただし、文字列をダブルクォートではなくシングルクォートで囲めば、
# 文字列は改行されずに1行として扱われる
'abc\nあ'.match /^[ -~。-゚]+$/
=> nil
-
(文字列).match /\A[正規表現の条件]\z/
... ○
文字列の途中に改行があったとしても、全ての行が条件に合致することをチェックしてくれる
# ダブルクォートでもシングルクォートでも同じ結果になる^^
"abc\nあ".match /\A[ -~。-゚]+\z/
=> nil
'abc\nあ'.match /\A[ -~。-゚]+z/
=> nil
参考URL
-
【jQuery】正規表現いろいろ
rubyじゃないけど、よく使われる正規表現がまとまっているので、rubyにも流用できる