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

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

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

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

正規表現

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

Q&A

解決済

2回答

1231閲覧

PHP正規表現の否定先読で「『否定部分』それ自体が、あるかないかわからない」というときの指定はありますか?

gongitune3

総合スコア12

PHP

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

正規表現

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

0グッド

0クリップ

投稿2020/08/02 09:34

編集2020/08/02 09:51

下記コードに並ぶ$urlのうち、最後の2つができなくて行き詰っています。

大まかにはhttps://example.com/●●▲▲
のような$urlが与えられ、
●●usだと不一致としたい
▲▲q=だと不一致としたい
という条件で、だいたいうまくできています。

しかしここに
●●▲▲もないときは一致としたい
という条件を追加することができません。

それが下記の最後の2つの$urlで、→ できないとある部分です。

php

1/* 2不一致にしたい$url 3************************/ 4$url = "https://example.com/us?q=aaa"; //「us」も「?q=」もあるので、不一致 5$url = "https://example.com/jp?q=aaa"; //「q=」があるので、不一致 6$url = "https://example.com/us?qx=aaa"; //「us」があるので、不一致 7$url = "https://example.com/us"; //「us」があるので、不一致 8$url = "https://example.com/?q=aaa"; //「q=」があるので、不一致 9$url = "https://example.com/?sort=date&q=aaa"; //「q=」があるので、不一致 10 11/* 12一致にしたい$url 13************************/ 14$url = "https://example.com/jp?qx=aaa"; //「us」も「q=」もないので、一致 15$url = "https://example.com/jp"; //「us」も「q=」もないので、一致 → できない 16$url = "https://example.com/"; //「us」も「q=」もないので、一致 → できない 17 18/* 19検証を実行 20************************/ 21$pattern = '{https?://example.com/(?!us)[a-z]{2}(?!\q=)[^/]+}'; 22var_dump( is_match($url,$pattern) ); 23function is_match( $url, $pattern ){ 24 if ( preg_match( $pattern, $url , $match ) ) { 25 return '一致'; 26 } else { 27 return '不一致'; 28 } 29}

日本語でいうと、「『否定部分(●●▲▲)』それ自体が、あるかないかわからない」ということになるのかと思います。

そのため、
➀後ろにはてなマークをつけて(否定部分[文字列])?という表現を試したのですが実現できず、
➁あと否定部分([文字列])?という風に文字列の部分だけをあるかないかわからないと表現したのも実現できず、
➂さらに否定部分|という風に、否定部分または何もないという表現も試したのですがやはり実現できず、このようなときはどうしたらよろしいでしょうか。

php

1// 上記コード 2$pattern = '{https?://example.com/(?!us)[a-z]{2}(?!?q=)[^/]+}'; 3 4// ➀後ろにはてなマークをつける表現 → 実現できず 5$pattern = '{https?://example.com/((?!us)[a-z]{2})?((?!?q=)[^/]+)?}'; 6 7// ➁否定部分の文字列の後ろにはてなマークをつける表現 → 実現できず 8$pattern = '{https?://example.com/(?!us)([a-z]{2})?(?!\q=)([^/]+)?}'; 9 10// ➂否定部分または何もないという表現 → 実現できず 11$pattern = '{https?://example.com/((?!us)[a-z]{2}|)((?!\q=)[^/]+|)}'; 12

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

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

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

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

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

thyda.eiqau

2020/08/02 10:06

目的は、機能を実現することと、正規表現を使うことと、どちらですか?
gongitune3

2020/08/02 10:19 編集

失礼いたしました。否定先読みを使った正規表現での実現を目指しています。is_matchは変えたくないです。
guest

回答2

0

ベストアンサー

NGなものをOR検索して、全体を否定するとかですかね・・・

投稿2020/08/03 00:36

yambejp

総合スコア114779

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

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

yambejp
gongitune3

2020/08/03 02:42

頭よすぎます!いつもありがとうございます。
guest

0

実用的には、

PHP

1$pat1 = '{\Ahttps?://example.com/}'; 2$pat2 = '{\Ahttps?://example.com/(us|.*\bq=)}'; 3 if ( preg_match( $pat1, $url) && !preg_match( $pat2, $url) ) {

投稿2020/08/02 10:14

otn

総合スコア84505

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

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

gongitune3

2020/08/02 10:18

なるほど。正規表現の否定は使わず、preg_matchの!に任せる方針ですか。たしかにわかりやすいです。参考にさせていただきます。
gongitune3

2020/08/03 00:33

もし正規表現の否定を使い、つまり質問のis_matchを使ったままでの方法でもしできましたら宜しくお願い致します。
otn

2020/08/03 00:43

可能かも知れませんが、メンテ困難は間違いなく、実用的ではないです。 実用じゃなくてパズルの領域。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問