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

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

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

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

Q&A

解決済

3回答

492閲覧

正規表現で指定した任意の数字を全体で1回づつ必ず使う指定は可能ですか?

opyon

総合スコア1009

正規表現

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

1グッド

2クリップ

投稿2018/08/28 23:37

編集2018/08/28 23:38

###実現したいこと
例えば3桁の数字で必ず1,2,3を各1回づつ必ず使うとした場合以下の結果が得られる正規表現での指定は可能でしょうか?

123 true
132 true
213 true
231 true
312 true
321 true
124 false

###わからないこと
正規表現で実現可能か不可能かがわからないのでそれだけでも知りたいです。

###試したこと
正規表現チェッカー
こちらのサイトで色々と試してみましたが正規表現では欲しい結果が得られそうにありませんでした。

イメージ説明

torisan👍を押しています

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

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

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

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

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

takasima20

2018/08/29 00:43

素直にソートして比較するのが分かりやすい気がするなあ
opyon

2018/08/29 01:01

回答頂く前にJavaでの実装は出来ていましたが、私のイメージで正規表現で処理出来たら冗長なコードいらないなぁと想像しましてこの質問に至りました。
opyon

2018/08/29 01:02

ここに辿り着いた方の参考のために後ほどサンプルコードを回答で提出しておきます。
guest

回答3

0

ベストアンサー

先読みを使えば実装可能です。

/^(?=.*1)(?=.*2)(?=.*3).{3}$/

前半の(?=.*1)は、「どこかに1が来る」という意味です(2屋3についても同じ)。

投稿2018/08/29 00:05

編集2018/08/29 00:07
maisumakun

総合スコア145184

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

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

opyon

2018/08/29 00:50

ありがとうございます。 出来ることが分かったことと実際のコードまで書いてくださったので実装してみて正規表現を使った場合と使わない場合の比較が出来ました。 正規表現はとても便利なので少しづつでも使っていきたいと思っています。
guest

0

maisumakunさんの回答で可能ですが、正規表現でAND条件は効率が悪いので私はお勧めしません。

  • 数字以外の文字に改行が含まれるなら、[\s\S]* もしくは修飾子s
  • 完全一致なのか、部分一致なのか

いろいろ考えるべきことはあります。
単純な部分一致のAND条件なら、他にふさわしい関数が用意されていると思います。

Re: opyon さん

投稿2018/08/29 00:24

think49

総合スコア18164

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

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

opyon

2018/08/29 00:59

ありがとうございます。 @maisumakunさんの回答で知りたかったこと(実現可否)に加え実装前後の比較が出来ました。 @think49さんの仰る「正規表現でAND条件は効率が悪い」ということも確認出来ました。 処理速度約2msから約6msになりました。 それは9桁で1-9の数字を各1回だけという処理なのでANDが9回重なり遅くなったのだと思います。 正規表現で出来ることを知っていればJavaコードなどで冗長な処理になるところがちょっとした工夫で簡潔になる場合も多々あるかと想像します。 正規表現には一長一短あるということが@maisumakunさんの回答と@think49さんのご指摘で両方得られたこの質問はとても勉強になりました。
guest

0

正規表現有り無しでの比較を参考までに提示しておきます。

"^(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).{9}$"
123456789 true
223456789 false

正規表現:正規表現チェッカー

イメージ説明
イメージ説明


参考問題
原文:Pandigital multiples Problem 38
翻訳:Problem 38 「パンデジタル倍数」

java

1import java.util.regex.Matcher; 2import java.util.regex.Pattern; 3 4public class pe_10038 { 5 6 public static void main(String[] args) { 7 long start = System.nanoTime(); 8 9 //例題 10 //192(1,2,3) 11 //192384576 12 13 func(9999); 14 //正規表現無し 15 // 9327 16 // 2 17 // 932718654 18 // 1.749699ms 19 long end = System.nanoTime(); 20 System.out.println((end - start) / 1000000f + "ms"); 21 System.out.println(); 22 23 start = System.nanoTime(); 24 func2(9999); 25 //正規表現有り 26 // 9327 27 // 2 28 // 932718654 29 // 6.028767ms 30 31 end = System.nanoTime(); 32 System.out.println((end - start) / 1000000f + "ms"); 33 } 34 35 static void func2(int n) { 36 int max = 0; 37 38 //正規表現有りの場合 39 40 //正規表現用 41 Pattern p1 = Pattern.compile( 42 "^(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)" 43 + "(?=.*6)(?=.*7)(?=.*8)(?=.*9).{9}$"); 44 Matcher m1; 45 46 for (int i = n; i > 0; i--) { 47 String s = ""; 48 for (int j = 1; j <= 9; j++) { 49 s += i * j; 50 51 int len = s.length(); 52 if (len > 9) { 53 break; 54 } else if (len < 9) { 55 continue; 56 } 57 58 //正規表現有りの場合 59 m1 = p1.matcher(s); 60 61 if (m1.find()) { 62 System.out.println(i); 63 System.out.println(j); 64 // System.out.println(s); 65 max = Math.max(max, Integer.parseInt(s)); 66 } 67 } 68 if (max != 0) { 69 System.out.println(max); 70 break; 71 } 72 } 73 } 74 75 static void func(int n) { 76 int max = 0; 77 78 //正規表現無しの場合 79 80 for (int i = n; i > 0; i--) { 81 String s = ""; 82 for (int j = 1; j <= 9; j++) { 83 s += i * j; 84 85 int len = s.length(); 86 if (len > 9) { 87 break; 88 } else if (len < 9) { 89 continue; 90 } 91 92 //正規表現無しの場合 93 if (chk(s)) { 94 System.out.println(i); 95 System.out.println(j); 96 // System.out.println(s); 97 max = Math.max(max, Integer.parseInt(s)); 98 } 99 } 100 101 if (max != 0) { 102 System.out.println(max); 103 break; 104 } 105 } 106 } 107 108 private static boolean chk(String s) { 109 int[] chk = new int[10]; 110 for (int i = 1; i <= 9; i++) { 111 chk[(s.charAt(i - 1) - '0')]++; 112 } 113 for (int i = 1; i <= 9; i++) { 114 if (chk[i] != 1) { 115 return false; 116 } 117 } 118 return true; 119 } 120}

投稿2018/08/29 01:16

opyon

総合スコア1009

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問