Regex per calcolare la mano di poker diretta - Utilizzando il CODICE ASCII
Domanda
In un'altra domanda ho imparato come calcolare la mano di poker diretta usando regex (Qui).
Ora, per curiosità, la domanda è: posso usare regex per calcolare la stessa cosa, usando il CODICE ASCII?
Qualcosa di simile a:
espressione regolare:[C][C+1][C+2][C+3][C+4], essendo C il CODICE ASCII (o simile)
Partite: 45678
, 23456
Non corrisponde: 45679
O 23459
(non in sequenza)
Soluzione 4
RISOLTO!
ho risolto utilizzando la chiusura, in 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())
}
Giusto per chiarire, codici ASCII:
codici 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
Altri suggerimenti
Il tuo problema principale sarà in realtà che non stai utilizzando codifiche ASCII consecutive per le tue mani, stai utilizzando numeri per le carte senza figure e caratteri non consecutivi e non ordinati per le carte con figure.
È necessario rilevare, all'inizio delle stringhe, 2345A, 23456, 34567, ..., 6789T, 789TJ, 89TJQ, 9TJQK
E TJQKA
.
Questi sono non codici ASCII consecutivi e, anche se lo fossero, incontreresti problemi poiché entrambi A2345
E TJQKA
sono validi e non otterrai A
essendo sia minore che maggiore degli altri caratteri nello stesso set di caratteri.
Se lo ha essere eseguito da una regex, quindi il seguente segmento regex:
(2345A|23456|34567|45678|56789|6789T|789TJ|89TJQ|9TJQK|TJQKA)
è probabilmente il più semplice e leggibile che otterrai.
Non c'è regex che farà quello che vuoi come le altre risposte hanno sottolineato, ma hai detto che vuoi imparare regex, quindi ecco un altro approccio meta-regex che può essere istruttivo .
Ecco un frammento Java che, data una stringa, programmaticamente generare il pattern che adattarsi a qualsiasi stringa di quella stringa di lunghezza 5.
String seq = "ABCDEFGHIJKLMNOP";
System.out.printf("^(%s)$",
seq.replaceAll(
"(?=(.{5}).).",
"$1|"
)
);
L'uscita è ( come visto in ideone.com ):
^(ABCDE|BCDEF|CDEFG|DEFGH|EFGHI|FGHIJ|GHIJK|HIJKL|IJKLM|JKLMN|KLMNO|LMNOP)$
È possibile utilizzare questo per generare comodamente il modello di espressione regolare per abbinare mani di poker rettilinei, inizializzando seq
a seconda dei casi.
Come funziona
. metacarattere href="http://www.regular-expressions.info/dot.html" rel="nofollow noreferrer"> corrisponde "qualsiasi" carattere (separatori di linea può essere un'eccezione a seconda sulla modalità siamo in).
Il {5}
è un esatto ripetizione identificatore. partite .{5}
esattamente 5 .
.
(?=…) IS href="http://www.regular-expressions.info/lookaround.html" rel="nofollow noreferrer"> positivo lookahead ; afferma che un dato modello può essere abbinato, ma poiché è solo un'affermazione, in realtà non fa (cioè consumano) partita dalla stringa di input.
Semplicemente (…)
è un cattura gruppo. Esso crea un backreference che è possibile utilizzare forse più tardi nel modello, o in sostituzione, o comunque si vede in forma.
Lo schema si ripete qui per comodità:
match one char
at a time
|
(?=(.{5}).).
\_________/
must be able to see 6 chars ahead
(capture the first 5)
Il modello funziona corrispondenza uno .
carattere alla volta. Prima di quel personaggio è abbinato, però, affermare (?=…)
che possiamo vedere un totale di 6 personaggi a venire (.{5}).
, catturando (…)
nel gruppo 1, la prima .{5}
. Per ognuna di queste partite, sostituiamo con $1|
, che è, ciò che è stato catturato dal gruppo 1, seguito dal metacarattere alternanza.
Consideriamo che cosa accade quando si applica ad un String seq = "ABCDEFG";
più breve. Il ↑
denota la nostra posizione corrente.
=== 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.
Così otteniamo ABCDE|BCDEF|CDEFG
, che sono tutte le stringhe di lunghezza 5 di seq
.
Bibliografia
Qualcosa come
regex: [C][C+1][C+2][C+3][C+4]
, essendoC
il codice ASCII (o come questo)
Non si può fare qualcosa di anche lontanamente vicino a questo nella maggior parte dei sapori regex. Questo non è semplicemente il tipo di modelli che regex è stato progettato per.
Non c'è regex tradizionale che succintly nessun due caratteri consecutivi che differiscono da x
nel loro codifica ASCII.
Per scopi didattici ...
Qui si va ( Vedi anche su 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)
);
}
Questo utilizza la tecnica meta-regexing per generare un modello. Che assicura modello che ogni carattere è seguito dal carattere destra (o la fine della stringa), utilizzando lookahead . Questo modello è quindi meta-regexed da abbinare più volte 5 volte.
È possibile sostituire alpha
con la sequenza di poker, se necessario.
Si noti che si tratta di un ASSOLUTAMENTE impraticabile soluzione. E 'molto più leggibile per esempio basta controllare se alpha.contains(test) && (test.length() == 5)
.