gpt4 book ai didi

.net - 至少两个唯一字符的正则表达式

转载 作者:行者123 更新时间:2023-12-04 16:22:29 26 4
gpt4 key购买 nike

我需要一个正则表达式来验证密码。

您可以假设输入仅包含小写字母 a-z。
限制是必须至少有两个唯一的字母。

请注意,我的意思是 唯一字符;不只是两个不同 字符。 (如果这是有道理的?)

例如,这些都可以:

abc
abbc
aabc

这些应该失败:
aabb    //There are no unique letters.  The 'a' appears twice.
aabbcc //There are no unique letters
abab //There are no unique letters
abb //There is only one unique letter

我知道只遍历字母会是一个更简单的解决方案,但不幸的是我需要它作为正则表达式。

我一直在尝试前瞻等的各种组合,但到目前为止没有运气。

编辑:

我取得了一些进展。我现在可以检查单个独特的字母,同时使用负向后视和负向前瞻。像这样:
(.)(?<!\1.+)(?!.*\1)

我希望我可以把它放两次,但它不起作用。类似于:
(.)(?<!\1.+)(?!.*\1)(.)(?<!\2.+)(?!.*\2)

最佳答案

这似乎可以解决问题:

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string[] values = { "abc", "abbc", "aabc", "aabb", "aabbcc", "abab", "abb" };
string pattern = @"(?:(.)(?<=^(?:(?!\1).)*\1)(?=(?:(?!\1).)*$).*?){2,}";
foreach (string value in values) {
if (Regex.IsMatch(value, pattern)) {
Console.WriteLine("{0} valid", value);
}
else {
Console.WriteLine("{0} invalid", value);
}
}
}
}

产生输出:
abc valid
abbc valid
aabc valid
aabb invalid
aabbcc invalid
abab invalid
abb invalid

可以在 Ideone 上看到: http://ideone.com/oU7a0

但是正则表达式是一个可怕的东西!

如果你愿意,我稍后会解释(我现在必须走了)。

编辑

好的,这是对这种怪物的解释(我希望!):
(?:                # start non-capture group 1
(.) # capture any character, and store it in match group 1
(?<= # start posisitve look-behind
^ # match the start of the input string
(?:(?!\1).) # if what is captured in match group 1 cannot be seen ahead, match the character
* # repeat the previous zero or more times
\1 # this is the `(.)` we're looking at
) # end posisitve look-behind
(?= # start posisitve look-ahead
(?:(?!\1).) # if what is captured in match group 1 cannot be seen ahead, match the character
* # repeat the previous zero or more times
$ # match the end of the input string
) # emd posisitve look-ahead
.*? # match zero or more characters, un-greedy
) # end non-capture group 1
{2,} # match non-capture group 1 at least 2 times

用简单的英语,它会有点像这样:
+---                                                      # (
| match and group any character `C` at position `P`, # (.)
| #
| and look from the start of the input all that way #
| to `P` where there can't be any character like `C` # (?<=^(?:(?!\1).)*\1)
| in between. #
| #
| Also look from position `P` all the way to the end #
| of the input where there can't be any character `C` # (?=(?:(?!\1).)*$)
| in bewteen. #
+--- #
| if the previous isn't matched, consume any character #
| un-greedy zero or more times (but the previous block # .*?
| is always tried before this part matched the character) #
+--- # )
| #
| #
+----> repeat this at least 2 times # {2,}

编辑二

假设 Kobi ( K ) 被放置在字符串顶部的某处, "abcYbacZa" , 包含 9 个字符:
              K
+---+---+---+---+---+---+---+---+---+
| a | b | c | Y | b | a | c | Z | a |
+---+---+---+---+---+---+---+---+---+

^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | |
p0 p1 p2 p3 p4 p5 p6 p7 p8

Kobi 想知道索引 4 处的字符是否为 Y , 在整个字符串中是唯一的。 Kobi 和他信任的仆从一起旅行,让我们称他为他的仆从 Bart ( B ),他从 Kobi 那里得到以下任务:

第1步

Kobi:Bart,回到输入的开头: regex: (?<=^ ... ) (Bart 将从位置 0 开始: p0 ,这是第一个 a 之前的空字符串);
B             K
+---+---+---+---+---+---+---+---+---+
| a | b | c | Y | b | a | c | Z | a |
+---+---+---+---+---+---+---+---+---+

^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | |
p0 p1 p2 p3 p4 p5 p6 p7 p8 p9

第2步

然后向前看,确定您是否看不到我在比赛组 1 中记住的字符, regex: (.) ,这是字符 Y .所以在位置 p0 , 巴特执行 regex: (?!\1) .对于 p0 ,这是正确的:Bart 看到字符 a ,所以 Y仍然是独一无二的。巴特前进到下一个位置 p1 ,在那里他看到了角色 b : 一切都还好,他又迈出了一步定位 p2 ,等等: regex: (?:(?!\1).)* .

第 3 步

巴特现在在位置 p3 :
            B K
+---+---+---+---+---+---+---+---+---+
| a | b | c | Y | b | a | c | Z | a |
+---+---+---+---+---+---+---+---+---+

^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | |
p0 p1 p2 p3 p4 p5 p6 p7 p8 p9

当他现在向前看时,他确实看到了字符 Y ,当然,所以 regex: (?!\1)失败。但是,Kobi 还在的那个角色被最后一个 \1 消耗掉了。在: regex: (?:(?!\1).)*\1 .所以在 p3之后,Bart 自豪地告诉 Kobi:“是的, Y 在我们身后看确实是独一无二的!”。 “很好”,Kobi 说,“现在做同样的事情,但不要向后看,而是向前看,一直到我们站立的这根绳子的末端,让它变得活泼!”。

第四步

巴特提示了一些难以理解的事情,但他的旅程开始于 p4 :
              K B
+---+---+---+---+---+---+---+---+---+
| a | b | c | Y | b | a | c | Z | a |
+---+---+---+---+---+---+---+---+---+

^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | |
p0 p1 p2 p3 p4 p5 p6 p7 p8 p9

当他向前看时,他看到了字符 b ,所以 regex: (?!\1)成立和性格 bregex: . 消耗. Bart 重复此操作零次或多次 regex: (?:(?!\1).)*一路输入 regex: (?:(?!\1).)*$结束.他再次回到科比,告诉他:“是的,展望 future , Y仍然是独一无二的!”

所以,正则表达式:
(.)(?<=^(?:(?!\1).)*\1)(?=(?:(?!\1).)*$)

将匹配字符串中唯一的任何单个字符。

第 5 步

上面的正则表达式不能简单地重复 2 次或更多次,因为它只能匹配 2 个连续的唯一字符。所以,我们将添加一个 regex: .*?之后:
(.)(?<=^(?:(?!\1).)*\1)(?=(?:(?!\1).)*$).*?
^^^

这将消耗字符 b , ac在这种情况下,并重复该正则表达式两次或更多次:
(?:(.)(?<=^(?:(?!\1).)*\1)(?=(?:(?!\1).)*$).*?){2,}
^^^ ^^^^^

所以最后,子串 "YbacZ"匹配自 "abcYbacZa"因为 YZ是独一无二的。

你有它,就像馅饼一样简单,对吧? :)

关于.net - 至少两个唯一字符的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5341369/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com