regex - 使用正则表达式确定顺子(无序手牌)

标签 regex

扑克中的顺子是连续五张牌,例如 2345689TJQ 。通过“排序”,正则表达式可以写成:

^(A2345|23456|34567|45678|56789|6789T|789TJ|89TJQ|9TJQK|TJQKA)$

这有点冗长,但足够简单。但是,如果手牌是无序的,是否可以生成(合理的)正则表达式?例如,如果手牌是 52634JQ89T ??

一种可能的方法是使用 ?=.*<item> 前瞻(本质上是“未排序的”),例如:

^(?:
     (?=.*A)(?=.*2)(?=.*3)(?=.*4)(?=.*5)
    |(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)
    |(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)
    |(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)
    |(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9)
    |(?=.*6)(?=.*7)(?=.*8)(?=.*9)(?=.*T)
    |(?=.*7)(?=.*8)(?=.*9)(?=.*T)(?=.*J)
    |(?=.*8)(?=.*9)(?=.*T)(?=.*J)(?=.*Q)
    |(?=.*9)(?=.*T)(?=.*J)(?=.*Q)(?=.*K)
    |(?=.*T)(?=.*J)(?=.*Q)(?=.*K)(?=.*A)
)
.{5}$

是否有其他/更好的方法来仅使用正则表达式查找是否存在顺子?

最佳答案

您可以使用以下正则表达式:

查看使用 here 的正则表达式

(?!.*(.).*\1)(?:[A2345]{5}|[23456]{5}|[34567]{5}|[45678]{5}|[56789]{5}|[6789T]{5}|[789TJ]{5}|[89TJQ]{5}|[9TJQK]{5}|[TJQKA]{5})

其工作原理是首先使用负前瞻来确保字符串不包含任何重复项(?!.*(.).*\1)。然后它会匹配任意直接可能的 5 个字符。

 (?!.*(.).*\1)
#^^^         ^ negative lookahead ensuring what follows doesn't match
#   ^^         match any character any number of times
#     ^^^      capture a character into capture group #1
#        ^^    match any character any number of times
#          ^^  match the same text as most recently matched by the 1st capture group

针对JQQ89,其工作原理如下: - .* 匹配 J - (.) 捕获 Q - .* 不匹配任何内容 - \1 尝试匹配 Q (并成功) - 负向预测有匹配,因此匹配失败。

关于regex - 使用正则表达式确定顺子(无序手牌),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58826075/

相关文章:

第一个括号之间的 Javascript 正则表达式字符串,包括括号内

c# - 仅在 .net 中的正则表达式灾难性回溯

javascript - 正则表达式和换行减号

javascript - 如何应用正则表达式将字符串转换为驼峰大小写并从字符串 Javascript 中删除所有特殊字符

mysql - 优化在 JOIN 中使用 REGEXP 的 SQL 查询

regex - 崇高文字立即将多个重音字符替换为无重音字符

python - 如何使用 re.search 只查找整个单词?

mysql - SQL正则表达式检查字符串是否包含某个子字符串

php - 如何在 Sublime Text Build 中获取文件夹名称

java - 单词之间的正则表达式