質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

4回答

1075閲覧

複雑な条件の正規表現でハマっています。

harajuku

総合スコア10

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

1クリップ

投稿2019/02/27 05:39

編集2019/02/27 06:19

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
PHPで会員登録フォームを作っており、現在バリデーションを実装中です。
氏名入力欄に、以下の条件で制限をかけたいと思っています。

◆許可
ひらがな
全角カタカナ
CJK統合漢字
"々"

◆不許可
それ以外

発生している問題・エラーメッセージ

正規表現で以下の指定をし、preg_matchを実行してみました。
上記の許可項目のいずれかのみで構成された文字列を想定したつもりです。

$pattern = '/^(((\xE4\xB8[\x80-\xFF])|\A(\xE5)|\A(\xE6)|\A(\xE7)|\A(\xE8)|(\xE9\xBF[\x00-\xAF]))|((\xe3\x81[\x81-\xff])|(\xe3\x82[\x00-\x9f])|(\xe3\x80\x85)))+$/'; $name = '田中たろう'; print_r(preg_match($pattern, $name)); >0

試したこと

ひらがな・カタカナ・CJK統合漢字に切り分けてそれぞれ実行してみたところ、CJK統合漢字の箇所に問題がありそうです。
Regexperを利用して画像化してみましたのが以下になります。

Regexper

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/02/27 05:42

「許可するもの」1つ1つ試した場合は通っているのでしょうか。
m.ts10806

2019/02/27 05:43

あ、あと'田中たろう'のあとに;が抜けているので修正願います。
harajuku

2019/02/27 06:12

ご指摘ありがとうございます。 1つ1つに分けたところ、CJK統合漢字が正常に働かず、そちらが怪しいかと睨んでいたところです…
guest

回答4

0

自分でコードポイント単位の処理をしなくても、PHP側でUnicode文字列プロパティが用意してあります。

なお、カタカナについては半角とヒットするのを避けるために文字範囲を使っています。

php

1$pattern= '/^(?:\p{Han}|\p{Hiragana}|[ァ-ヶ]|々)*$/u';

投稿2019/02/27 05:45

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/02/27 05:48

正規表現を「/.../u」の形にすれば、文字コードUTF-8で、1文字がUnicode1文字と対応するようになります。uなしで自力でやるのは手間だし誤爆の危険も高まります。
maisumakun

2019/02/27 05:55

いま気づきましたが、1つ問題がありまして、\p{Han}には、CJK統合漢字以外の漢字もヒットしてしまいます。
harajuku

2019/02/27 06:07

閲覧とご回答ありがとうございます。 ご回答いただいた記述ですと大分スマートですね! CJK統合漢字の扱いが難しそうですね…
guest

0

質問者さんの言う「CJK統合漢字」というのは以下の U+4E00 ~ U+9FFF の文字で良いのでしょうか?

イメージ説明

違うような気もしますが、それで良ければ、U+3040 ~ U+30FF が「ひらがな」と「全角カタカナ」、U+4E00 ~ U+9FFF が「CJK統合漢字」ということで正規表現パターンは、

^([\u3040-\u30FF]|[\u4E00-\u9FFF]|々)+$

でいかがでしょう? 

"々" は U+3005 で「ひらがな」「全角カタカナ」「CJK統合漢字」いずれにも含まれないと理解しています。

投稿2019/02/27 06:21

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

harajuku

2019/02/27 06:51

閲覧とご回答ありがとうございます。 CJK統合漢字の範囲につきましてはおっしゃる通りです。 ご提示いただいた記述そのままですと正常に認識して貰えない様ですので、引き続き調べてみます。
退会済みユーザー

退会済みユーザー

2019/02/27 07:17

PHP では [\u4E00-\u9FFF] という書き方ではなくて、以下の記事を見ると、 https://tama-san.com/?p=196 [\x{4E00}-\x{9FFF}] というようになるのでしょうか? 無知ですみません。
harajuku

2019/02/27 07:31

とんでもないです。 そちらの記事も参考に引き続き調査を進めて参ります。ありがとうございます。
guest

0

バイト単位で見るべきではないと思いますが、それはそうと問題点は以下のあたりかなと思います。
① 2バイトめがB8のみになっているが3バイトめのようにあり得る範囲を示すべき所
② 間違っているとまでは言えないが、不正なバイト列も受け付けている
③ \Aは「文字列の先頭」の意味だと思うが、ここにあると複数文字を取れない
④ E4やE9と同様に3バイトのパターンを示すべきだが1バイトだけとっている
⑤ ①と同様
⑥ 00からなのは不正なバイト列も受け付けるし、AFまでなのは途中で切れている
それと、CJK統合漢字はF9xxあたりの互換漢字ゾーンにもいくつかありますので厳密にいくならそれらも入れるべきです。
f365a45e0ae09bb53ebd5cb87a8c5375.png

投稿2019/02/27 16:56

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

harajuku

2019/02/28 00:19

分かりやすくご指摘いただきありがとうございます。とても助かります。 ご指摘の箇所をもう一度見直してみたいと思います。
guest

0

確認浅かったようです。失礼しました。

^って現在の箇所につけた場合、「否定」だったと思います。

これをとったらうまくいきそうに思いますが、いかがでしょうか。

投稿2019/02/27 05:47

編集2019/02/27 05:48
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

harajuku

2019/02/27 06:05

閲覧とご回答ありがとうございます。承知いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問