我只涉足正则表达式,想知道是否有人可以帮助我制作一个 Java 正则表达式,它与具有以下特性的字符串相匹配:
它应该匹配
但不是
我尝试过以下正则表达式字符串
[a-zA-Z^\\-_]+[\\-_]?[a-zA-Z^\\-_]*
Run Code Online (Sandbox Code Playgroud)
这似乎有效。但是,我不确定如何用这种方法来完成总字符限制部分。我也尝试过
[[a-zA-Z]+[\\-_]?[a-zA-Z]*]{1,14}
Run Code Online (Sandbox Code Playgroud)
但它匹配(例如) abc-cde_aa ,但它不应该匹配。
这应该有效:
(?![_-])(?!(?:.*[_-]){2,})[A-Za-z_-]{1,14}
Run Code Online (Sandbox Code Playgroud)
正则表达式非常复杂,让我尝试解释一下。
(?![_-])负前瞻。从字符串的开头断言第一个字符不是_or -。负向先行“查看”当前位置并检查它是否与包含和[_-]的字符组不匹配。_-(?!(?:.*[_-]){2,})另一个否定的前瞻,这次匹配(?:.*[_-]){2,}是一个非捕获组,重复至少两次。组是.*[_-],它是任何字符,后跟与之前相同的组。所以我们不希望看到某些字符出现一次_或-多次。[A-Za-z_-]{1,14}是简单的一点。它只是说出该组中的字符[A-Za-z_-]1 到 14 次。该模式的第二部分是最棘手的,但却是一个非常常见的技巧。如果您希望看到某个字符A在模式中的某个点至少重复几次,那么您希望至少X看到该模式多次,因为您必须有.*AX
zzzzAzzzzAzzzzA....
Run Code Online (Sandbox Code Playgroud)
你不在乎还有什么。所以你得到的是(.*A){X,}. 现在,您不需要捕获该组 - 这只会减慢引擎的速度。所以我们让该组成为非捕获 - (?:.*A){X,}。
您所拥有的是您只想看到该模式一次,因此您不希望发现该模式重复两次或多次。因此,它插入负前瞻。
这是一个测试用例:
public static void main(String[] args) {
final String pattern = "(?![_-])(?!(?:.*[_-]){2,})[A-Za-z_-]{1,14}";
final String[] tests = {
"Hello-Again",
"ThisIsValid",
"AlsoThis_",
"_NotThis_",
"-notvalid",
"Not-Allow-This",
"Nor-This_thing",
"VeryVeryLongStringIndeed",
};
for (final String test : tests) {
System.out.println(test.matches(pattern));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
true
true
true
false
false
false
false
false
Run Code Online (Sandbox Code Playgroud)
注意事项:
-在字符组中是特殊的。它必须位于组的开头或结尾,否则它指定一个范围{}非常有用。它有 3 个状态。{X}被精确地重复了X几次。{X,}至少重复多次X。并且在和之间{X, Y}重复。XY