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

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

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

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

正規表現

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

Q&A

2回答

1061閲覧

php URL形式の文字列をpreg_matchを使用して特定の文字列を含んでいるor含んでいないをしたいのですがうまくいきません。

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

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

正規表現

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

0グッド

0クリップ

投稿2021/06/11 21:10

前提・実現したいこと

タイトルの通りで、URL形式の文字列内に指定した文字列を含んでいるかのチェックをしたいのですが、中々うまくいかないので質問させていただきました。

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

下記のような文字列に対し、preg_matchを使用して含んでいるかどうかの判定をしています。

$str = "https://example.com/example.jpg&w=200&h=283"; $str2 = "https://example.com/example.jpg"; $pt = "{(?!.*&w=200&h=283)}"; if (preg_match($pt, $str) === 0) { echo "1"; }else { echo "2"; } if (preg_match($pt, $str2) === 0) { echo "1"; }else { echo "2"; }

上記のコードを実行すると、どちらのifも2を返してしまいます。
1つ目のifは1を返してほしいのですが、これはどこが間違っているのでしょうか?
よろしくおねがいします。

試したこと

デリミタの文字を#や^に変更。

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

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

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

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

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

m.ts10806

2021/06/11 22:53

preg_match でなければならないのでしょうか。 「含んでるかどうか」だけならstrposとかもっと簡単なものもあるように思いますが。
guest

回答2

0

正規表現が間違っています。

(?!.*&w=200&h=283)(?!は否定先読みで、「これ以降に&w=200&h=283が無い」という意味で、否定先読み以外に何も中身が無いので、全体としては、「それ以降に&w=200&h=283が無い空文字列」にマッチします。

PHP

1$r = preg_match($pt, $str, $m, PREG_OFFSET_CAPTURE); 2var_dump($r); 3var_dump($m);

するとわかりますが、このときは32バイト目の空文字列にマッチしています。
つまり、&w=200&h=283&wの隙間ですね。この隙間以降の文字列はw=200&h=283ですが、その中に&w=200&h=283は存在しないのでマッチしたわけです。

文字列を探すだけであれば、コメントにあるようにstr_pos等の正規表現を使わない関数が簡明です。
また、正規表現を使う場合も「~~を含まない」を正規表現で実現しようとするのは不可能もしくは可能であっても正規表現初心者には難しいので、正規表現は「~~を含む」にして置いて、否定はPHP側の機能でするのが良いです。

gas.engineさんの回答参照。

あと、そもそも、https://example.com/example.jpg&w=200&h=283というようなURLは無いはずで、
https://example.com/example.jpg?w=200&h=283とかhttps://example.com/example.jpg?a=11&w=200&h=283とかですよね。

また、https://example.com/example.jpg?w=200&h=28399のようなURLにマッチして欲しいのかどうか?マッチして欲しくないのでは?

ということから考えると、正規表現は、

PHP

1$pt = "/[&?]w=200&h=283\b/";

でしょうか。一般的にはw=h=の順不同や途中にに別の変数が挟まる考慮も必要です。

投稿2021/06/12 03:45

otn

総合スコア84559

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

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

0

preg_match

引用テキストpreg_match() は、pattern が指定した subject にマッチした場合に 1 を返します。 マッチしなかった場合は 0、エラーが発生した場合は false を返します。

1つ目で、マッチしたときに1を返すためには、1にする必要があります。
if (preg_match($pt, $str) === 1) {

デリミタは以下のどれでもいいようです。
デリミタ

php

1/foo bar/ 2#^[^0-9]$# 3+php+ 4%[a-zA-Z0-9_-]%

最終的にこれでどうでしょうか?

php

1$str = "https://example.com/example.jpg&w=200&h=283"; 2$str2 = "https://example.com/example.jpg"; 3$pt = "/.*&w=200&h=283/"; 4 5if (preg_match($pt, $str)===1) { 6 echo "1"; 7}else { 8 echo "2"; 9} 10 11if (preg_match($pt, $str2)===1) { 12 echo "1"; 13}else { 14 echo "2"; 15} 16

投稿2021/06/11 23:18

gas.engine

総合スコア608

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問