Grep升序卡。它为什么有效?

时间:2016-12-28 12:40:40

标签: regex bash unix grep

我需要grep的卡片集合定义为:

{h ∈ H | h contains only cards in ascending order regardless of their suit} 

示例:

h = Ah2c2d3s5h6d8s8d9h9cTdTcKh   
h != 3d4dQc3sKcAh2sAc7hKdKsKh4h62 (Q is followed by lower rank 3)

上升的牌组是:

A(ace) 2 3 4 5 6 7 8 9 T(ten) J Q K 

诉讼定义如下:

c(clover) s(spade) h(heart) d(diamond)

我已经尝试了以下grep并且它是正确的但我仍然没有 明白它为何有效。

编辑***添加了-P标志(忘了它),正如三人组所指出的那样grep -v确实无效。

 grep -Pv "[KQJT].*[2-9A].* |[KQ].*[JT].* |[6-9].*[2-5A].* "

让我感到困惑的是K followed by Q如何与此模式匹配甚至是5 followed by [A2-4]

该解决方案总共有31027 lines

可以在此处找到为练习提供的文本文件: http://computergebruik.ugent.be/oefeningenreeks1/kaarten1.txt

1 个答案:

答案 0 :(得分:1)

你的正则表达式完全无效,所以我不明白为什么你说它有效。

普通grep不理解|是指更改。您可以添加-E选项以指定ERE(传统上,egrep)正则表达式语义,或使用POSIX grep反斜杠|;或者您可以指定多个-e选项。 (有关常用的各种正则表达方言的背景,请参阅例如https://en.wikipedia.org/wiki/Regular_expression#Standards。)

grep -Ev "[KQJT].*[2-9A].* |[KQ].*[JT].* |[6-9].*[2-5A].* "
grep -v  "[KQJT].*[2-9A].* \|[KQ].*[JT].* \|[6-9].*[2-5A].* "
grep -ve "[KQJT].*[2-9A].* " -e "[KQ].*[JT].* " -e "[6-9].*[2-5A].* "

即使使用此修复程序,正则表达式显然也不足以删除匹配,例如3之后是2.使其涵盖所有案例的唯一方法是列举所有可能性。 (禁止1后跟任何更高的数字,2后跟任何更高的数字,3后跟任何更高的数字,等等。)更好的方法是使用某种脚本语言,并且基本上只是将符号映射到具有所需的排序顺序,然后检查输入是否已排序。

如果这不是一个选项,可以尝试

grep -E '^(A.)*(2.)*(3.)*(4.)*(5.)*(6.)*(7.)*(8.)*(9.)*(T.)*(J.)*(Q.)*(K.)* '

查找零个或多个aces,后跟零个或多个两个,然后是零个或多个三个等等。