java正则表达式,只允许一组字符中的1个
我试图使用一些正则表达式来验证Java代码内部的一些输入。我已经成功地实现了“basic”regex,但是这个似乎超出了我的知识范围。我正在通过RegEgg教程学习更多内容
以下是需要验证的条件:
- 字段将始终有8个字符
- 可以是所有空间
或
- 有效字符:a-zA-Z0-9-&;还是一个空间
- 不能以空格开头
- 如果使用了其中一个特殊字符,则只能使用该字符 法律:“B-123——”AB&;&;&“A!!!!!!!” 非法:“B-123!!!”“AB&;-”A-&;!“李>
- 必须至少有一个字母数字字符(不能都是特殊字符,例如:“!!!!!!!!!”李>
在添加其他验证之前,这是我的正则表达式:
^(\s{8}|[A-Za-z\-\!\&][ A-Za-z0-9\-\!\&]{7})$"
现在的附加验证允许多个特殊字符,我有点卡住了。我成功地使用了积极的前瞻,但在尝试使用积极的前瞻时遇到了困难。(我认为Lookback之前的数据已经被使用了),但我在猜测,因为我对regex的这一部分是新手
# 1 楼答案
使用or构造(
a|b
)是其中的一大部分,您已经开始应用它,因此这是一个良好的开端您已经制定了规则,它不能以数字开头;规范中没有这么说。另外,
-
内的[]
有特殊的含义,所以要避开它,或者确保它是第一个或最后一个,因为这样你就不必这样做了。这使我们能够:^(\s{8}|[A-Za-z0-9-!& -]{8})$
如果下一个字符使用的是同一个字符,那么它将被使用。考虑到只有3个特殊字符,只需显式列出它们就更容易了:
^(\s{8}|[A-Za-z0-9 -]{8}|[A-Za-z0-9 !]{8}|[A-Za-z0-9 &]{8})$
下一步:不能从一个空间开始,也不能完全特别。确认否定(并非所有特殊字符)变得复杂;展望未来似乎是一个更好的计划。这:
^
是“行的开始”的regexp-ese。请注意,这不会“消耗”字符1
是regexpse,表示“这里只有确切的字符“1”匹配,其他什么都不匹配”,但当它匹配时,它也会“使用”该字符,而^
不会这样做。”“线路起点”不是一个可以使用的概念“匹配可能失败,但如果成功,则不会消耗任何东西”的概念不限于
^
和$
;你可以自己写:如果
abc
在该位置匹配,则(?=abc)
将匹配,但不会消耗它。因此,regexp^(=abc)ab.d$
将与输入字符串abcd
匹配,而不匹配其他内容。这称为正向前瞻。(如果在parens中看到正则表达式,它会“向前看”并匹配,如果没有,则会失败)(?!abc)
是负前瞻性的。如果看不到parens中的东西,则匹配(?!abc)a.c
将匹配输入adc
,但不匹配输入abc
(?<=abc)
是积极的后视。它匹配您提供的模式是否匹配,以便匹配在您找到自己的位置结束(?<!abc)
是负向后看注意,lookahead和lookahead可能有一些限制,因为它们可能不允许可变长度的模式。但是,幸运的是,您的需求使我们很容易将自己限制在固定大小的模式中。因此,我们可以在regexp中引入:
(?![&!-]{8})
作为一个非消耗单元,如果我们有全部8个特殊字符,它将导致匹配失败我们也可以使用这个技巧在启动空间上失败:
(?! )
就是我们所需要的让我们用
替换
\s
,它是空格,它是空格字符(问题描述是“空格”,而不是“空格”)总而言之:
^( {8}|(?! )(?![&!-]{8})([A-Za-z0-9 -]{8}|[A-Za-z0-9 !]{8}|[A-Za-z0-9 &]{8}))$
那就是:
在regex101处插入它们以及各种“合法”和“不合法”的示例,您可以进一步使用它们
注意:您也可以使用反向引用来尝试解决其中的“仅允许一个特殊字符”部分,但是如果您不使用(负面)前瞻,则尝试解决“并非所有特殊字符”部分似乎相当笨拙
# 2 楼答案
这是一个在正则表达式开始时断言正确条件的问题
^(?=[ ]*$|(?![ ]))(?!.*([!&-]).*(?!\1)[!&-])[a-zA-Z0-9 !&-]{8}$
见->https://regex101.com/r/tN5y4P/1
一些讨论: