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

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

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

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

正規表現

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

Q&A

解決済

3回答

606閲覧

【PHP正規表現】利用可能文字種のうち、x種以上を使う

tablow

総合スコア14

PHP

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

正規表現

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

0グッド

1クリップ

投稿2018/04/04 03:21

PHPの正規表現で、下記条件を表現する書き方を探しております。

【条件】
下記の利用可能文字種のうち、最低2種類が利用されていること

【利用可能文字種】
<半角英小文字>
abcdefghijklmnopqrstuvwxyz

<半角英大文字>
ABCDEFGHIJKLMNOPQRSTUVWXYZ

<半角数字>
0123456789

<半角記号>
!"#$%&'()*+,-./:;<=>?@[]^_`{|}~

現状のコードは下記の通りです。

^.*(?=.{3,})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\d\X])(?=.*[!"#$%&'()*+,\-./:;<=>?@[¥]^_`{|}~]).*$

どうぞ、よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

4回マッチさせて回数を数えるのが一番手っ取り早い気がします

PHP

1$p1="/[abc]/"; 2$p2="/[ABC]/"; 3$p3="/[123]/"; 4 5$matches=[]; 6$str="a3x"; 7preg_match($p1,$str,$matches[0]); 8preg_match($p2,$str,$matches[1]); 9preg_match($p3,$str,$matches[2]); 10print $str.":".(count(array_filter($matches,function($x){return count($x)>0;}))>=2?"OK":"NG")."<br>"; 11 12$matches=[]; 13$str="abx"; 14preg_match($p1,$str,$matches[0]); 15preg_match($p2,$str,$matches[1]); 16preg_match($p3,$str,$matches[2]); 17print $str.":".(count(array_filter($matches,function($x){return count($x)>0;}))>=2?"OK":"NG")."<br>";

追記

こっちのほうがまともなアプローチかもしれません

PHP

1function check($str){ 2 $pattern="/([abc])|([ABC])|([123])/"; 3 preg_match_all($pattern,$str,$matches); 4 array_shift($matches); 5 return count(array_filter($matches,function($x){ 6 return count(array_filter($x,function($y){ 7 return $y!==""; 8 }))>0; 9 })); 10} 11print check("xyz"); 12print check("abcx"); 13print check("a3x"); 14print check("abc123xyz"); 15print check("aB3"); 16print check("abcABC123xyz"); 17

投稿2018/04/04 03:40

編集2018/04/04 05:33
yambejp

総合スコア114769

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

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

退会済みユーザー

退会済みユーザー

2018/04/04 03:47

私の回答より、こっちのほうが後で読みやすそうですね^^ preg_match の返り値、合致で 1 を返すんで、単純に足し算して 2 以上とかでも良さそう。
tablow

2018/04/04 03:48

ご回答いただきまして、誠にありがとうございますmm 大変、参考になりました。
yambejp

2018/04/04 03:50 編集

te2jiさん、ご指摘ありがとうございます たしかにmatchだけ利用しているならカウンタをインクリメントするだけで 事足りますね ちょっと無駄な技術に走りすぎたかもしれません
退会済みユーザー

退会済みユーザー

2018/04/04 05:01

別回答作ってて気が付きましたが、文字種縛りをどっかで書かないといけませんね。 これだと、全角含むやつが通ってしまう。
退会済みユーザー

退会済みユーザー

2018/04/04 08:21

追記の方も文字種の縛りが必要かと。
退会済みユーザー

退会済みユーザー

2018/04/04 08:22

`全角aBc`とかが通ってしまいます。
guest

0

めちゃくちゃ面倒くさそうなんで、考え方だけ^^;

<半角英小文字>+それ以外
or
<半角英大文字>+それ以外
or

な感じで列挙するとできます。
要するに先頭文字種を判定して、それ以外が一つでもあるか?って判定です。
多分、それぞれの文字種を変数に入れて正規表現を作ってやらないと、間違いが起きると思います。

投稿2018/04/04 03:42

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

tablow

2018/04/04 03:52

ご回答、誠にありがとうございます。 参考にさせていただきたいと思いますmm
guest

0

よく考えたら、同一文字種以外で4種の組み合わせであれば良いので、以下でイケそうです。

php

1<?php 2$symbol = preg_quote('!"#$%&\'()*+,-./:;<=>?@[]^_`{|}~', '/'); 3$pattern_1 = '(?!((\A[a-z]+\z)|(\A[A-Z]+\z)|(\A[0-9]+\z)|(\A['.$symbol.']+\z)))'; 4$pattern_2 = '(?=((\A[a-z|A-Z|0-9|'.$symbol.']+\z)))'; 5$pattern = '/' . $pattern_1 . $pattern_2 . '/'; 6 7echo '$pattern : ' . $pattern . PHP_EOL; 8 9$words = [ 10 '1', 11 'test', 12 '!"#', 13 '1a', 14 'Test', 15 'q!', 16 '1Test?', 17 ]; 18 19foreach ($words as $test) { 20 $result = preg_match($pattern, $test)?'match':'miss match'; 21 echo $result . ':' . $test . PHP_EOL; 22}
$pattern : /(?!((\A[a-z]+\z)|(\A[A-Z]+\z)|(\A[0-9]+\z)|(\A[\!"#$%&'()*+,\-./\:;\<\=\>?@[\]^_`\{\|\}~]+\z)))(?=((\A[a-z|A-Z|0-9|\!"#$%&'()*+,\-./\:;\<\=\>?@[\]^_`\{\|\}~]+\z)))/ miss match:1 miss match:test miss match:!"# match:1a match:Test match:q! match:1Test?

投稿2018/04/04 04:56

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yambejp

2018/04/04 05:05

細かく見てませんが 本文では2種類となっているので必要十分かもしれませんが、 元の命題がx種類以上なのでこれって3種類以上でもいけます?
退会済みユーザー

退会済みユーザー

2018/04/04 05:05

いえ、イケないですw 自己満足回答ですw
退会済みユーザー

退会済みユーザー

2018/04/04 05:07

多分、 yambejp さんの回答みたいに、合算値でしきい値を設けるのが一番読みやすくてわかりやすいかと^^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問