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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

878閲覧

URLリストを一致した条件ごとに分けたい

LeCreuset

総合スコア15

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/12/29 11:33

編集2019/12/29 20:27

前提

jQueryのeachを用い、URLを検証するシステムを作っています。
例えば以下input_url_arrの5つのURLが検証対象となるURLだとします。

js

1const input_url_arr = [ 2 'https://yahoo.com/jp/0', 3 'https://goo gle.com/xxx/1', 4 'https://google.com/jp/2', 5 'https://google.com/jp/3', 6 'https://yahoo.com/jp/1' 7];

###実現したいこと

上記input_url_arrを下記のように整理したいです。

「どのURLがどのサービスに属すかを示したい」ということと、そして「もしどこにも属さないURLがあればそのURLはどんな理由によって属さないのかを示したい」というのが目的です。

js

1 { 2 // もしどこにも属さないURLがあればそのURLはどんな理由によって属さないのかを示したい 3 error_arr: 4 [ 5 { "https://goo gle.com/xxx/1": 6 [ 7 "valided_pattarn is not valid.", // xxxが正規表現と不一致という理由でエラー 8 "space is not valid." // スペースがあるという理由でエラー 9 ] 10 } 11 ], 12 13 // どのURLがどのサービスに属すかを示したい 14 yahoo: 15 [ 16 'https://yahoo.com/jp/0', 17 'https://yahoo.com/jp/1' 18 ], 19 google: 20 [ 21 'https://google.com/jp/2', 22 'https://google.com/jp/3' 23 ] 24 }

発生している問題

'https://goo gle.com/xxx/1'xxxの部分が[a-z]{2}に不一致であり、さらにスペースもあるという理由によってエラーとし、上記のようにerror_arrに入れたいのですが、これが入りません。

そして他の4つは正規表現の条件をクリアしているので、上記のようにサービス名の配列に入れたいのですが、これも入りません。

該当のソースコード

下記を実行するjsfiddle

js

1const input_url_arr = [ 2 'https://yahoo.com/jp/0', 3 'https://goo gle.com/xxx/1', 4 'https://google.com/jp/2', 5 'https://google.com/jp/3', 6 'https://yahoo.com/jp/1' 7]; 8const result = valid_supplier_url( input_url_arr ) 9console.log( result ); 10 11function valid_supplier_url( input_url_arr ){ 12 13 // yahooのパターン 14 const pattern_yahoo = [ 15 'https://yahoo.com/[a-z]{2}/[0-9]{2}', 16 // 他にもいくつかある 17 ]; 18 19 // googleのパターン 20 const pattern_google = [ 21 'https://google.com/[a-z]{2}/[0-9]{2}', 22 // 他にもいくつかある 23 ]; 24 25 // ホワイトリスト 26 const white_list = { 27 yahoo : pattern_yahoo, 28 google: pattern_google 29 }; 30 31 // 結果 32 let result = {}; 33 34 // 引数の input_url_arr を検証 35 let valided_pattarn; 36 $.each( input_url_arr, function( i, input_url ) { 37 38 // ホワイトリストとの検証 39 $.each( white_list, function( supplier, patterns ) { 40 $.each(patterns, function( i, pattern ) { 41 console.log( 'input_url「'+input_url+'」' ); 42 if ( input_url.match(pattern) ) { 43 result[supplier] = []; 44 result[supplier].push( input_url ); 45 valided_pattarn = true; 46 return false; 47 } 48 }); 49 }); 50 51 // 基本URLパターンの検証 52 const common_url = new RegExp( 53 '^(https?:\/\/)?'+ // protocol 54 '((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|'+ // domain name 55 '((\d{1,3}\.){3}\d{1,3}))'+ // OR ip (v4) address 56 '(\:\d+)?(\/[-a-z\d%_.~+]*)*'+ // port and path 57 '(\?[;&a-z\d%_.~+=-]*)?'+ // query string 58 '(\#[-a-z\d_]*)?$','i' // fragment locator 59 ); 60 const valided_common = input_url.match( common_url ); 61 62 // エラー内容を入れる 63 if ( valided_pattarn && valided_common ) { 64 // ホワイトリストとの検証もtrueで、基本URLパターンの検証もtrueなのでこの場合はエラーなし 65 } 66 else{ 67 if ( input_url.slice(0,4) !== 'http' ){ 68 result['error_arr'] = { [input_url]: 'http is not valid.' }; 69 } 70 if ( input_url.match(/,/) ) { 71 result['error_arr'] = { [input_url]: 'comma is not valid.' }; 72 } 73 if ( input_url.match(/ /) || input_url.match(/ /) ) { 74 result['error_arr'] = { [input_url]: 'space is not valid.' }; 75 } 76 if ( ! valided_pattarn ){ 77 result['error_arr'] = { [input_url]: 'valided_pattarn is not valid.' }; 78 } 79 if ( ! valided_common ) { 80 result['error_arr'] = { [input_url]: 'common_url is not valid.' }; 81 } 82 } 83 84 }); 85 86 return result; 87}

試したこと

おそらくjsfiddleの43行目の
result[supplier] = [];
によって、ホワイトリストとの一致が毎回リセットされてしまうために生じるのではないかと推察しました。

そこで新たにmatchedという配列を宣言し、次のように修正を試みました。

このmatchedを改めて
result[supplier] = matched;
で追加するという流れにしてみたのですが、これでも実現できず・・・

といったような考察をするレベルです。

js

1 // ホワイトリストとの検証 2 $.each( white_list, function( supplier, patterns ) { 3 $.each(patterns, function( i, pattern ) { 4 console.log( 'input_url「'+input_url+'」' ); 5 if ( input_url.match(pattern) ) { 6 result[supplier] = []; 7 result[supplier].push( input_url ); 8 valided_pattarn = true; 9 return false; 10 } 11 }); 12 }); 13 14/*** ↓修正 ****/ 15 16 // ホワイトリストとの検証 17 $.each( white_list, function( supplier, patterns ) { 18 let matched = []; /*** ←追加 ****/ 19 $.each(patterns, function( i, pattern ) { 20 console.log( 'input_url「'+input_url+'」' ); 21 if ( input_url.match(pattern) ) { 22 //result[supplier] = []; /*** ←削除 ****/ 23 //result[supplier].push( input_url ); /*** ←削除 ****/ 24 matched.push( input_url ); /*** ←追加 ****/ 25 valided_pattarn = true; 26 return false; 27 } 28 }); 29 result[supplier] = matched;/*** ←追加 ****/ 30 }); 31 32

先に挙げました2つの問題についての対策や修正方法についてアドバイス頂けましたら幸いです。
どうぞ宜しくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

正規表現オブジェクトが生成されていません。

javascript

1let regexp = new RegExp(pattern); 2console.log( regexp.source ); 3 4if ( input_url.match(regexp) ) { 5 /* omitted */ 6}

追記)

$.each() 以前の問題として、正規表現マッチパターンが尽く間違っていますので、上記の回答をしました。話しにならないのです。

以下のパターンマッチをチェックしてください。

javascript

1input_url_arr.forEach( url => { 2 let m = url.match(regexp_common_url); 3 console.log( m ); 4/* 5入力 : "https://yahoo.com/jp/0" 6結果 : ["https://yahoo.com/jp/0", "https://", "yahoo.com", "yahoo.", "yahoo", "ahoo", undefined, undefined, undefined, "/0", undefined, undefined] 7*/ 8})

ドメイン名が取得するなら、 supplier はその値で切り分ければいい。

jQueryのeachを用い、URLを検証するシステムを作っています

$.each() を用いて、処理コストしかない多重ループで構築すべきではないと思います。

CODE PEN parseURL()


多重ループを使う場合は正規表現を正しく使ってください。

投稿2019/12/29 12:16

編集2020/01/01 11:02
AkitoshiManabe

総合スコア5432

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

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

LeCreuset

2019/12/29 19:56

失礼しました。大事なご指摘をありがとうございます。
LeCreuset

2019/12/31 08:31

追記拝見させていただきました。parseURL() には驚きました。いろいろな機会で使わせて頂くことがありそうな関数で、どうもありがとうございます。 結局正規表現とループと問題が2つありますので、まずは正規表現を使わずに、parseURL() の流れを引用して試してみました↓ https://jsfiddle.net/b2fuetpL/ しかし、やはりループの方で上書きの問題が生じてしまいました。(50行目で上書きされ、値が1つしか入らないという点です。) ひとまずこのループ時の上書きという問題に絞って別の質問を投稿させて頂き、そちらが解決しましたらまた改めてこちらの質問に取り組んでみようと思っていますので、後程またご報告させて頂きます。
AkitoshiManabe

2019/12/31 08:42

ご返信のリンク先を見ました。「// ←これが1つしか追加されない」のは毎回初期化されているからですね。 初期化部分は1回に抑制できますよ。 r[supplier] || (r[supplier] = []); // if ( !r[supplier] ) r[supplier] = []; のイディオム
LeCreuset

2019/12/31 11:11

またすさまじく便利な勉強になる書き方をどうもありがとうございます。おかげ様で思っていたよりもいい感じにできました。
LeCreuset

2020/01/01 07:52 編集

解決とした件で恐れいります。 検証が「>ドメイン名が取得するなら、 supplier はその値で切り分ければいい」という方法ですと、「https://yahoo.google.com/jp/0」のようなURLに対処できない等の問題が生じてしまったので、やはり質問の流れに則って組むことに致しました。 そうなってくると、ループの上書き問題は教えて頂いたイディオムで解決できるものの、error_arr になぜかエラーではないURLまで入ってしまうという別の問題にぶちあたってしまいました。 それがこちらなのですが… https://jsfiddle.net/h8dfs4j1/ 50行目で return false; している時点でループから抜けているはずなのに、なぜか error_arr にすべてのURLが入ってしまう現状です。 年始早々申し訳ございませんが、もし余力がございましたら引き続きアドバイス頂けましたら幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問