我在 ruby 中实现以下问题。
这是我想要的模式:
1234、1324、1432、1423、2341 等
即四位数字中的数字应该在[1-4]之间并且也应该是非重复的。
为了让您以简单的方式理解,我采用两位数模式,解决方案应为:12、21
即数字应该是 1 或 2 并且应该是非重复的。
为了确保它们不重复,我想使用 $1 作为我的第二个数字的条件,但它不起作用。
请帮助我并提前感谢。
我在 ruby 中实现以下问题。
这是我想要的模式:
1234、1324、1432、1423、2341 等
即四位数字中的数字应该在[1-4]之间并且也应该是非重复的。
为了让您以简单的方式理解,我采用两位数模式,解决方案应为:12、21
即数字应该是 1 或 2 并且应该是非重复的。
为了确保它们不重复,我想使用 $1 作为我的第二个数字的条件,但它不起作用。
请帮助我并提前感谢。
您可以使用它(参见 rubular.com):
^(?=[1-4]{4}$)(?!.*(.).*\1).*$
第一个断言确保它是^[1-4]{4}$
,第二个断言是一个否定的前瞻,确保你不能匹配.*(.).*\1
,即重复的字符。第一个断言是“更便宜”,所以你想先这样做。
只是为了傻笑,这是另一种选择:
^(?:1()|2()|3()|4()){4}\1\2\3\4$
随着每个唯一字符的使用,它后面的捕获组捕获一个空字符串。反向引用也尝试匹配空字符串,因此如果其中一个不成功,则只能表示关联的组没有参与匹配。只有当字符串包含至少一个重复项时才会发生这种情况。
这种空捕获组和反向引用的行为在任何正则表达式风格中都不受官方支持,因此请注意 emptor。但它适用于其中的大多数,包括 Ruby。
I think this solution is a bit simpler
^(?:([1-4])(?!.*\1)){4}$
See it here on Rubular
^ # matches the start of the string
(?: # open a non capturing group
([1-4]) # The characters that are allowed the found char is captured in group 1
(?!.*\1) # That character is matched only if it does not occur once more
){4} # Defines the amount of characters
$
(?!.*\1)
is a lookahead assertion, to ensure the character is not repeated.
^
and $
are anchors to match the start and the end of the string.
虽然前面的答案解决了这个问题,但它们并没有尽可能通用,并且不允许在初始字符串中重复。例如,{a,a,b,b,c,c}
。在对Perl Monks提出类似问题后,Eily给出了以下解决方案:
^(?:(?!\1)a()|(?!\2)a()|(?!\3)b()|(?!\4)b()|(?!\5)c()|(?!\6)c()){6}$
同样,这适用于字符串中较长的“符号”,也适用于可变长度的符号。