正規表現ストレートポーカーハンドを計算する - ASCIIコードを使用して

StackOverflow https://stackoverflow.com/questions/3482151

  •  28-09-2019
  •  | 
  •  

質問

ここ).

さて、好奇心によって、問題は次のとおりです。 ASCIIコードを使用して、同じことを計算するためにRegexを使用できますか?

何かのようなもの:

regex:[c] [c+1] [c+2] [c+3] [c+4]、c the asciiコード(またはこれが好き)

マッチ: 45678, 23456

一致しません: 45679 また 23459 (順番ではありません)

役に立ちましたか?

解決 4

解決した!

を参照してください http://jsfiddle.net/g48k9/3

JSで閉鎖を使用して解決しました。

String.prototype.isSequence = function () {
    If (this == "A2345") return true; // an exception
    return this.replace(/(\w)(\w)(\w)(\w)(\w)/, function (a, g1, g2, g3, g4, g5) {
        return    code(g1) == code(g2) -1 &&
                code(g2) == code(g3) -1 &&
                code(g3) == code(g4) -1 &&
                code(g4) == code(g5) -1;
    })
};

function code(card){
    switch(card){
        case "T": return 58;
        case "J": return 59;
        case "Q": return 60;
        case "K": return 61;
        case "A": return 62;
        default: return card.charCodeAt();
    }
}


test("23456");
test("23444");
test("789TJ");
test("TJQKA");
test("8JQKA");

function test(cards) {
    alert("cards " + cards + ": " + cards.isSequence())
}

明確にするために、ASCIIコード:

ASCIIコード:

2 = 50
3 = 51
4 = 52
5 = 53
6 = 54
7 = 55
8 = 56
9 = 57
T = 84 -> 58
J = 74 -> 59
Q = 81 -> 60
K = 75 -> 61
A = 65 -> 62

他のヒント

あなたの主な問題は、実際には、手にASCIIにかかるエンコーディングを使用していないこと、フェイスカードではないカードに数字を使用していないこと、およびフェイスカードには順序でないキャラクターを使用しているということです。

文字列の開始時に検出する必要があります。 2345A, 23456, 34567, ..., 6789T, 789TJ, 89TJQ, 9TJQKTJQKA.

これらは いいえ 連続したASCIIコードと、たとえそうであったとしても、あなたは両方から問題に遭遇するでしょう A2345TJQKA 有効であり、あなたは取得しません A 同じ文字セットの他のキャラクターよりも少なく、大きい。

それであれば もっている 正規表現によって行われるには、次の正規表現セグメント:

(2345A|23456|34567|45678|56789|6789T|789TJ|89TJQ|9TJQK|TJQKA)

おそらくあなたが得る最も簡単で最も読みやすいものです。

他の答えが指摘したようにあなたが望むことをすることをする正規表現はありませんが、あなたはあなたがしたいと言いました 学び 正規表現なので、ここに教育的かもしれない別のメタレゲックスアプローチがあります。

ここに、文字列が与えられたJavaスニペットがあり、その文字列の長さ5のサブストリングに一致するパターンをプログラム的に生成します。

    String seq = "ABCDEFGHIJKLMNOP";
    System.out.printf("^(%s)$",
        seq.replaceAll(
            "(?=(.{5}).).",
            "$1|"
        )
    );

出力は(ideone.comで見られるように):

^(ABCDE|BCDEF|CDEFG|DEFGH|EFGHI|FGHIJ|GHIJK|HIJKL|IJKLM|JKLMN|KLMNO|LMNOP)$

これを使用して、初期化することにより、ストレートポーカーハンドに合わせて正規表現パターンを便利に生成できます seq 適切に。


使い方

. メタカラクター 「任意の」文字に一致します (ラインセパレーターは、私たちが入っているモードに応じて例外である場合があります)。

{5} 正確です 繰り返し 指定器。 .{5} ちょうど5つ一致します ..

(?=…)ポジティブ 先のことを考える;特定のパターンを一致させることができると断言しますが、それは単なるアサーションであるため、実際には入力文字列から一致を行いません(つまり、消費します)。

単に (…) aです キャプチャグループ. 。これは、おそらくパターンの後半、置換、または適切であると思われるものを使用できることを背景にします。

便利なためにパターンはここで繰り返されます:

     match one char
        at a time
           |
(?=(.{5}).).
\_________/
 must be able to see 6 chars ahead
 (capture the first 5)

パターンは、1つの文字を一致させることで機能します . 一度に。しかし、そのキャラクターが一致する前に、私たちは主張します (?=…) 合計6文字先に見ることができること (.{5})., 、キャプチャ (…) 最初のグループ1に .{5}. 。そのような試合ごとに、私たちは置き換えます $1|, 、つまり、グループ1が捉えたものは何でも、その後に代替Metacharacterが続きます。

これを短いものに適用すると何が起こるか考えてみましょう String seq = "ABCDEFG";. 。 現在の位置を示します。

=== INPUT ===                                    === OUTPUT ===

 A B C D E F G                                   ABCDE|BCDEFG
↑
We can assert (?=(.{5}).), matching ABCDEF
in the lookahead. ABCDE is captured.
We now match A, and replace with ABCDE|

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
  ↑
We can assert (?=(.{5}).), matching BCDEFG
in the lookahead. BCDEF is captured.
We now match B, and replace with BCDEF|

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
    ↑
Can't assert (?=(.{5}).), skip forward

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
      ↑
Can't assert (?=(.{5}).), skip forward

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
        ↑
Can't assert (?=(.{5}).), skip forward

       :
       :

 A B C D E F G                                   ABCDE|BCDEF|CDEFG
              ↑
Can't assert (?=(.{5}).), and we are at
the end of the string, so we're done.

だから私たちは得ます ABCDE|BCDEF|CDEFG, 、これはすべての長さ5のサブストリングです seq.

参照

何かのようなもの regex: [C][C+1][C+2][C+3][C+4], 、 であること C ASCIIコード(またはこれが好き)

ほとんどのregexフレーバーでは、これに近いものは何もできません。これは、正規表現のために設計された種類のパターンではありません。

異なる2つの連続したキャラクターを成功して一致させる主流の正規表現パターンはありません x ASCIIエンコードで。


教育目的のために...

どうぞ (IDEONE.comも参照してください):

    String alpha = "ABCDEFGHIJKLMN";
    String p = alpha.replaceAll(".(?=(.))", "$0(?=$1|\\$)|") + "$";

    System.out.println(p);
    // A(?=B|$)|B(?=C|$)|C(?=D|$)|D(?=E|$)|E(?=F|$)|F(?=G|$)|G(?=H|$)|
    // H(?=I|$)|I(?=J|$)|J(?=K|$)|K(?=L|$)|L(?=M|$)|M(?=N|$)|N$

    String p5 = String.format("(?:%s){5}", p);

    String[] tests = {
        "ABCDE",    // true
        "JKLMN",    // true
        "AAAAA",    // false
        "ABCDEFGH", // false
        "ABCD",     // false
        "ACEGI",    // false
        "FGHIJ",    // true
    };
    for (String test : tests) {
        System.out.printf("[%s] : %s%n",
            test,
            test.matches(p5)
        );
    }

これは、メタレゲックス技術を使用してパターンを生成します。そのパターンにより、各文字の後に正しい文字(または文字列の端)が続くことが保証されます。 先のことを考える. 。そのパターンは、メタレジーであり、5回繰り返し一致します。

代用することができます alpha 必要に応じてポーカーシーケンスを使用してください。

これはです 絶対に非現実的です 解決。たとえをチェックするだけではるかに読みやすいです alpha.contains(test) && (test.length() == 5).

関連する質問

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top