我一直在努力应对这些糟糕的事情。我记得一位讲师告诉我们所有人,如果你有一个问题要求你使用正则表达式解决它,你实际上现在有2个问题。
嗯,我当然同意这一点。正则表达式是我们不经常使用的东西,但是当我们这样做时,就像阅读一些外来语言一样(对我而言)...我想我会决定拿到这本书并进一步阅读。
我遇到的挑战是,我需要根据以下标准验证用户名:
.
)和下划线(_
)__
..
,但._._
有效。到目前为止,我有以下内容:^[a-zA-Z_.]{0,20}$
但当然它允许重复下划线和句号。
现在,我可能做错了,从有效字符集和最大长度开始。我一直在尝试(不成功)创建一些环视或后视或其他什么来搜索无效的句点重复(.
)和下划线(_
)不确定的方法或方法将此要求分解为正则表达式解决方案是。
任何人都可以协助推荐/替代方法或指出我正确的方向吗?
答案 0 :(得分:9)
这是你需要的那个:
^(?:[a-zA-Z0-9]|([._])(?!\1)){5,20}$
您可以演示它匹配的内容here。
“alphanum char([a-zA-Z0-9]
)或(|
)一个点或一个下划线([._]
),但它本身不会跟随({ {1}}),以及5到20次((?!\1)
)。“
{5,20}
只是非捕获组,即您之后无法使用(?:X)
,\1
或{{ 1}}语法。
$1
被称为否定前瞻,即字面意思是“其后没有X”。
?1
指的是第一个捕获组。由于第一组(?!X)
已设置为非捕获(请参阅#1),因此第一个捕获组为\1
。
(?:...){5,20}
表示从X到Y次,您可以根据需要进行更改。
答案 1 :(得分:6)
您可以使用两个negative lookahead assertions:
^(?!.*__)(?!.*\.\.)[0-9a-zA-Z_.]{0,20}$
<强>说明:强>
(?! # Assert that it's impossible to match the following regex here:
.* # Any number of characters
__ # followed by two underscores in a row
) # End of lookahead
根据您的要求和正则表达式引擎,您可以将[0-9A-Za-z_.]
替换为[\w.]
。
@sp00n提出了一个好点:你可以将前瞻断言合并为一个:
^(?!.*(?:__|\.\.))[0-9a-zA-Z_.]{0,20}$
这可能会更有效率,但有点难以阅读。
答案 2 :(得分:6)
不要试图把它推到一个正则表达式。您的单个正则表达式适用于除#4之外的所有条件。要执行#4,只需执行与无效用户名匹配的正则表达式,如果匹配则拒绝用户名。例如(伪代码):
if username.matches("^[a-zA-Z_.]{0,20}$") and !username.matches("__|\\.\\.") {
/* accept username */
}