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

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

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

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

Q&A

解決済

2回答

2509閲覧

引数のオプションの入力チェック関数

miu_ras

総合スコア902

JavaScript

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

0グッド

0クリップ

投稿2016/01/22 14:35

引数のオプションの値の入力チェックの関数の実装の話です。

絶対条件
・オプションは文字列で指定される
・オプションはなくてもいい(長さ0バイトの空文字)
・abcABCだけで構成されている
・順は問わない

OK例
・""
・"a"
・"aBc"
・"bac"

NG例
・"abcd"

上記の条件を満たす関数はすぐに出来ました。

JavaScript

1function checkOption(o) { 2 return /^[abcABC]*$/.test(o); 3}

ここで、さらに
「同じ文字の複数回の登場は許可しない」という制約を追加したいのですが、一見簡単そうなことなのに手が止まってしまいました。

NG
・"aba"

正規表現で1行でシンプルに書くことは出来ませんかね。仮に出来なくとも、複数行でも正規表現でなくともいいので、出来るだけシンプルスマートな方法を探しています。これを教えてください。

よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

「引数が String 型でない時」の条件が抜けていますが、「String 型に変換して評価する」でいいのでしょうか。
自己解決されたコードでもいいと思いますが、文字数もチェックすると長大な文字列を判定するときの結果が早く出そうですね。

JavaScript

1'use strict'; 2function checkAbc (string) { 3 return /^[abcABC]{0,6}$/.test(string) && !/([abcABC])[abcABC]*\1/.test(string); 4} 5 6console.log(checkAbc('')); // true 7console.log(checkAbc('aBc')); // true 8console.log(checkAbc('BaCAbc')); // true 9console.log(checkAbc('aA')); // true 10console.log(checkAbc('aa')); // false

スマートなコードとなると汎用性が高いコードだと個人的には考えていますが、いろいろと書き方があります。
コードが長くても汎用性の高いコードは美しいと思います。

JavaScript

1'use strict'; 2var checkString1 = (function (String, RegExp){ 3 return function checkString1 (characterClass, string) { 4 var l; 5 6 characterClass = String(characterClass); 7 string = String(string); 8 l = characterClass.length; 9 10 if (string.length > l) { 11 return false; 12 } 13 14 characterClass = '[' + characterClass.replace(/(?=\W)/g, '\\') + ']'; 15 16 return new RegExp('^' + characterClass + '{0,' + l + '}$').test(string) && !(new RegExp('(' + characterClass + ')' + characterClass + '*\\1').test(string)); 17 }; 18}(String, RegExp)); 19 20var checkString2 = (function (String, RegExp){ 21 return function checkString2 (characterClass, string) { 22 var cl, l, i, char; 23 24 characterClass = String(characterClass); 25 string = String(string); 26 cl = characterClass.length; 27 l = string.length; 28 29 if (l > cl) { 30 return false; 31 } 32 33 i = 0; 34 35 while (i < l) { 36 char = string[i++]; 37 38 if (characterClass.indexOf(char) === -1) { 39 return false; 40 } 41 42 characterClass = characterClass.replace(new RegExp(char.replace(/(?=\W)/, '\\'), 'g'), ''); 43 } 44 45 return true; 46 }; 47}(String, RegExp)); 48 49console.log(checkString1('abcABC', '')); // true 50console.log(checkString1('abcABC', 'aBc')); // true 51console.log(checkString1('abcABC', 'BaCAbc')); // true 52console.log(checkString1('abcABC', 'aA')); // true 53console.log(checkString1('abcABC', 'aa')); // false 54 55console.log(checkString2('abcABC', '')); // true 56console.log(checkString2('abcABC', 'aBc')); // true 57console.log(checkString2('abcABC', 'BaCAbc')); // true 58console.log(checkString2('abcABC', 'aA')); // true 59console.log(checkString2('abcABC', 'aa')); // false

Re: miu_ras さん

投稿2016/01/23 11:51

think49

総合スコア18156

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

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

miu_ras

2016/01/24 09:47 編集

長さ制限をするのはいいですね。参考にします。 ありがとうございました 後半のコードは私は苦手です。 引数で汎用的にするにしても、私の場合はここまでですね。 function checkOption(o, v) {   var reg = new RegExp("^[" + o + "]{0," + o.length + "}$");   return reg.test(v) && !/(.).*\1/.test(v); } function checkOption(opts, v) {   var REG_BODY = "^[【opts】]{0,【len】}$";   var reg = new RegExp(REG_BODY.replace("【opts】", opts).replace("【len】", o.length));   return reg.test(v) && !/(.).*\1/.test(v); }
think49

2016/01/25 00:45

その書き方ですと、「引数の型の想定」と「正規表現判定」が不十分な為に期待通りの結果を返さないケースがあります。 「引数が String 型でない時」の条件が抜けてるト言ったのはそういう理由です。TypeError を返す設計もありえます。 function checkOption(o, v) {   var reg = new RegExp("^[" + o + "]{0," + o.length + "}$");   return reg.test(v) && !/(.).*\1/.test(v); } // 引数が String 型ではない場合 console.log(checkOption([1,2], '1,2')); // false console.log(checkOption({}, '[object Object]')); // false // 引数が改行コードを含む場合 console.log(checkOption('abc\n', 'a\na')); // true // 引数が正規表現メタキャラクタを含む場合 console.log(checkOption('[]abc', '[]abc')); // false console.log(checkOption('abc\\', 'abc\\')); // SyntaxError: Invalid regular expression: /^[abc\]{0,4}$/: Unterminated character class
guest

0

あれ?単純にこれでいいのかな…。

JavaScript

1function checkOption(o) { 2 return /^[abcABC]*$/.test(o) && !/(.).*\1/.test(o); 3}

もしもっといい方法があったら、それを教えてくださいよろしくお願いします。

投稿2016/01/22 15:21

miu_ras

総合スコア902

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問